Spring Boot前端Jsp與thymeleaf共存
簡介 | |
一、前言
不久前才接觸SpringBoot,並嘗試使用thymeleaf做為視圖解析器,就在想是否能同時使用jsp與thymeleaf,網路上有不少人提供解決方法,但是依照其所提供的解決方法做卻一直無法實現兩者共存,後來終於找到原因,重點就是那麼簡單。
二、專案設定
1. 建立Spring Started Project
File->New->Spring Starter Project
輸入專案資訊
選擇配置dependency,「spring web」、「thymeleaf」
2. 設定pom.xml
使用thymeleaf則需要有以下的dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
要用Jsp則需要有以下的dependency
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
3. 設定application.properties
設定網頁開啟的網址路徑及通訊埠,其餘參數在ViewResolver中設定。
server.servlet.context-path=/thjsp
server.port=8083
三、解決方法與實作
1. 建立網頁檔案存放資料目錄
網頁檔案應放置於「src/main/webapp/ WEB-INF」下,若無此目錄,請新增目錄「WEB-INF」。
在「src/main/webapp/WEB-INF/」建立資料夾「jsp」以放置jsp網頁檔案;
在「src/main/webapp/WEB-INF/」建立資料夾「th」以放置thymeleaf的html檔案。
2. 增加解析器類別
InternalResourceViewResolver:jsp的視圖解析器
ThymeleafViewResolver:thymeleaf的視圖解析器
viewResolver.setPrefix:只設定為web的預設目錄「/WEB-INF/」,不加上網頁檔案所存在的資料目錄,而在controller回傳值才加上檔案所在目錄路徑。
viewResolver.setViewNames:未設定時預設都會解析jsp網頁,但有設定只會依設定值解析該目錄中的網頁。
viewResolver. setOrder():若jsp 解析器與thymeleaf解析器有設定到相同的目錄,則以order為判斷,數字越小優先權越高。
import org.springframework.context.annotation.Bean;
...
@Configuration
@EnableWebMvc
@ComponentScan
public class ViewResolverConfiguration extends WebMvcConfigurationSupport {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
//不在此加上jsp檔案所在資料目錄,而在controller回傳值才加上檔案所在目錄
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".jsp");
resolver.setViewNames("jsp/*");
resolver.setOrder(1);
return resolver;
}
@Bean
public ITemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setTemplateMode("HTML");
//不在此加上jsp檔案所在資料目錄,而在controller回傳值才加上檔案所在目錄
templateResolver.setPrefix("/WEB-INF/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("utf-8");
templateResolver.setCacheable(false);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
@Bean
public ThymeleafViewResolver viewResolverThymeLeaf() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("utf-8");
viewResolver.setOrder(2);
viewResolver.setViewNames(new String[]{"html/*", "vue/*","templates/*","th/*"});
//網頁檔案存放目錄需符合viewNames中的值才可被成功解析顯示
return viewResolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
增加Controller
網址列輸入localhost:8083:thjsp/jsp,則應該開啟jsp/jsphome.jsp頁面。
網址列輸入localhost:8083:thjsp/th,則應該開啟th/thhome.html頁面。
@Controller
@RequestMapping("/")
public class indexController {
@RequestMapping("/jsp")
public String toJspHome(Model model) {
model.addAttribute("today", new Date());
model.addAttribute("welcome", "這是jsp頁面"));
return "jsp/jsphome";
}
@RequestMapping("/th")
public String toVue(Model model) {
model.addAttribute("today", new Date());
model.addAttribute("today", "這是thymeleaf頁面");
return "th/thhome";
}
}
jsphome.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> jspHome.jsp </title>
</head>
<body>
<h2>${welcome}</h2>
<p>現在時間: ${today}</p>
</body>
</html>
thhome.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset=utf-8">
<title>thome.html</title>
</head>
<body>
<h2 th:text="${welcome}"></h2>
<p th:text="'現在時間: ' +${today}"></p>
</body>
</html>
四、執行結果
專案執行(Run As Spring Boot App)後,
於瀏覽器輸入http://localhost:8083/thjsp/th/ 則顯示thymeleaf網頁,
輸入http://localhost:8083/thjsp/jsp/ 則顯示jsp網頁,顯示結果如下圖
以上步驟完成,即可同時使用jsp與thymeleaf做為view解析器顯示。
不過依上述步驟經多次實作,結果發現有更簡單的做法不用建立ViewResolver類別能達成兩者並存。
1. 在application.properties 設定「spring.mvc.view.prefix=/WEB-INF/」、「spring.thymeleaf.prefix=/WEB-INF/」。
2. 再於controller的返回值加上欲開啟網頁的存放目錄,如「return "th/thhome";」「return "jsp/jsphome";」。
3. 執行後於Browser上輸入「http://localhost:8083/thjsp/th/」即可顯示thymeleaf頁面,Browser上輸入「http://localhost:8083/thjsp/jsp/」即可顯示jsp頁面。
application.properties
thjspController.java
瀏覽結果
五、總結
其實能達成jsp與thymeleaf視圖並存的重點有幾點:
1. 於application.properties中thymeleaf.prifix目錄只設定「/WEB-INF/」,而不加上視圖所存放資料夾路徑。
2. 於controller的return返回值加上欲開啟網頁的存放資料夾路徑。
3. 設定application.properties的thymeleaf.view-names或是ViewResolver的viewNames屬性,設定的值即為該ViewResolver會存放的路徑與格式,若非在此設定範圍內,controller返回時無法顯示指定的thymeleaf頁面或是只執行指定目錄中的符合名稱的.jsp頁面。
下圖範例為spring.thymeleaf 的view-names輸入「th/*,vue/*」,
jsp目錄下同時放置「jsphome.jsp、jsphome.html」,controller中返回jsp/jsphome,執行結果會選擇開啟jsphome.jsp。
vue目錄中同時放置「thhome.jsp」「thhome.html」,controller中返回vue/thhome,執行結果會選擇開啟thhome.html。
因接觸不久,或許做法有不完善或是還有其他做法,也請不吝分享,謝謝。
六、分享
GitHub: https://github.com/chunchiYen/JspAndThymeleaf