SpringBoot第九集:整合JSP和模板引擎Freemarker/Thymeleaf(2020最新最易懂)
SpringBoot第九集:整合JSP和模板引擎(2020最新最易懂)
當客戶通過前端頁面提交請求後,我們以前是怎麼做的?後端接收請求資料,處理請求,把響應結果交給模板引擎JSP,最後將渲染後的JSP轉為HTML,響應給客戶端顯示。JSP的好處就是當我們查出一些資料轉發到JSP頁面以後,我們可以用JSP輕鬆實現資料的顯示,及互動等。JSP支援非常強大的功能,包括能寫Java程式碼。
但是呢,我們現在的這種情況是,第一:SpringBoot這個專案首先是以jar的方式,不是war。第二:我們用的還是嵌入式的Tomcat(簡化版的,即不支援JSP),所以呢,SpringBoot預設是不支援JSP的。如果我們直接用純靜態頁面的方式,那給我們開發會帶來非常大的麻煩,因此我們不得已選擇,除了JSP外的其他模板引擎。
模板引擎的作用就是,我們來寫一個頁面模板, 比如有些值,是動態的,我們在通過寫一些表示式,來動態的顯示這些值,就像我們早前常用的JSP。模板引擎的作用其實都一樣,只不過呢,不同模板引擎之間,他們可能這個語法有點不一樣。Spring Boot支援FreeMarker、Groovy、Thymeleaf和Mustache四種模板解析引擎,官方推薦使用Thymeleaf。
對於模版引擎而言,SpringBoot
預設存放模版檔案的路徑為src/main/resources/templates
,當然也可以通過配置檔案進行修改的。
當然了,使用JSP也是可以的,但官方已經不建議使用JSP
了,本文也會講解下SpringBoot
JSP
的支援的,因為有很多老的專案還是使用JSP模板的
居多。(不推薦使用JSP也是因為JSP需要編譯轉換,而其他模板引擎則無需編譯轉換)
1.SpringBoot整合Java Server Page
JSP(全稱Java Server Page),是web開發最早期的模板引擎產品,隨著時代的更新,已漸漸老去,當然目前還未完全退出市場。SpringBoot微服務架構,所有專案都是以jar檔案方式打包部署,嵌入式的Tomcat(簡化版,不支援JSP),所以SpringBoot預設是不支援JSP的,那麼如果想要整合JSP,就需要獨立引入整合依賴,和基礎配置。
SpringBoot
src/main/resources/templates,但由於SpringBoot預設是不支援JSP的,所以我們不能將JSP檔案放在templates目錄下。
- 引入JSP核心引擎
1 <!-- SpringBoot整合JSP:SpringBoot預設整合Tomcat,所以不需要指定JSP版本 --> 2 <dependency> 3 <groupId>org.apache.tomcat.embed</groupId> 4 <artifactId>tomcat-embed-jasper</artifactId> 5 </dependency> 6 <!-- JSP依賴JSTL --> 7 <dependency> 8 <groupId>javax.servlet</groupId> 9 <artifactId>jstl</artifactId> 10 </dependency>
- 建立JSP整合目錄webapp以及WEB-INF
在Java,resources同級目錄下新建webapp目錄及子目錄WEB-INF
至於web.xml配置檔案,是可要可不要了。
- 修改yml檔案,配置MVC試圖解析器
1 spring: 2 # 配置整合JSP 3 mvc: 4 view: 5 # 配置檢視解析器字首 6 prefix: /WEB-INF/ 7 # 配置檢視解析器字尾 8 suffix: .jsp
- 建立Controller跳轉訪問JSP
因為是返回頁面 所以不能是@RestController
// @RestController 該註解會將任何返回值都作為JSON暴露,不經過檢視解析器 @Controller // SpringBoot整合JSP,不能使用@RestController public class PersonController { @RequestMapping({"/indexJSP","/listJSP"}) public String getIndexJSP() { System.out.println("JSP訪問測試。。。。。"); return "index"; } }
- 啟動SpringBoot主程式,訪問測試
http://localhost:8080/indexJSP
1.說明:在完成上面的步驟之後,執行專案就可以訪問jsp介面,但是別高興的太早,當你打成一個jar包的時候,你會發現你不能訪問jsp了,原因是SpringBoot打包時,是不會主動打包webapp目錄的,你需要在你的pom檔案手動配置把webapp的檔案打包進去。詳情參考附錄。
2.常見錯誤:沒有手動重啟伺服器!導致無法解析,錯誤程式碼500,顯示資訊:template might not exist or might not be accessible by any of the configured Template Resolvers(模板可能不存在,或者任何配置的模板解析程式都無法訪問)
3.如果只是整合JSP,不整合使用其他模板,那麼請不要引入其他模板依賴,也無需配置其他模板資訊,否則會錯錯錯!!!(SpringBoot預設支援的模板引擎,自然也有對應的預設配置,一旦你添加了對應的依賴,SpringBoot將遵循約定大於配置,自動注入,那你的JSP也就無法訪問了)。
2.SpringBoot整合Freemarker
FreeMarker 是一款模板引擎: 即一種基於模板和要改變的資料, 並用來生成輸出文字(HTML網頁,電子郵件,配置檔案,原始碼等)的通用工具。 它不是面向終端使用者的,而是一個Java類庫,是一款程式設計師可以嵌入他們所開發產品的元件。官網參考
在Spring Boot中使用FreeMarker 只需在pom中加入FreeMarker 的starter即可。
- 修改pom檔案引入FreeMarker 的starter
1 <!-- SpringBoot整合Freemarker --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-freemarker</artifactId> 5 </dependency>
- 修改yml檔案配置FreeMarker
(可以不配,SpringBoot預設支援該模板)
1 spring: 2 # Freemarker配置詳解(都含有預設配置) 3 freemarker: 4 # 模板載入路徑(預設配置就是templates下,可以手動配置,多值使用“,”分割) 5 template-loader-path: 6 - classpath:/templates/ 7 # 配置快取,開發階段應該配置為false 因為經常會改,部署後建議開啟 8 cache: false 9 # 配置編碼設定 10 charset: UTF-8 11 # 建議模版是否存在 12 check-template-location: true 13 # Content-Type 值 14 content-type: text/html 15 # 模板字尾:預設為ftlh(這裡測試更改為了html),如果你設定了模板字尾,那麼新建的模板檔案必須為指定字尾 16 # suffix: .html 17 # 是否啟用Freemarker 18 enabled: true 19 # 詳解配置可以檢視FreeMarkerProperties類
配置說明:這裡是向廣大朋友概述/舉例常見配置,並不是所有的都需要,SpringBoot含有預設配置,詳情參考
org.springframework.boot.autoconfigure.freemarker.FreeMarkerProperties
類,上面的配置中,實際僅配置關閉快取即可。 - 新建FreeMarker模板
在src/main/resources/templates/下新建模板引擎。
FreeMarker模板預設字尾為ftlh,如果沒有自定義配置,請遵循約定大於配置的初衷,新建模板且字尾設定為.ftlh。如果有自定義配置,則新建模板字尾為自定義的。例如:當前案例上面配置指定字尾為.html,那麼新建的模板字尾就是.html,不必擔心,會不會不支援FreeeMarker語法的問題。(模板引擎最終還是會轉換為HTML的)
Feemarker語法:參考官網,參考中文網
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Insert title here</title> 6 </head> 7 <body> 8 Hello Freemarker!!! 9 <#-- FreeMarker註釋:獲取數值(注意:這裡的${}是FreeMarker語法,類似於EL,要清楚這不是EL表示式,且這裡的值不是null,否則會報錯) --> 10 ${name } 11 </body> 12 </html>
- 編寫Controller控制器,實現跳轉訪問
1 @Controller // 因為是返回頁面 所以不能是@RestController 2 public class FreemarkerController { 3 4 @RequestMapping("/indexFtlh") 5 private String freemarkerShowIndex(String name, Model model) { 6 // 將接受的引數通過model共享(實際儲存在request中) 7 model.addAttribute("name", name); 8 return "indexFtlh"; 9 } 10 }
- 啟動主程式測試
訪問:http://localhost:8080/indexFtlh?name=xsge
常見錯誤:沒有手動重啟伺服器!導致無法解析,錯誤程式碼500,顯示資訊:template might not exist or might not be accessible by any of the configured Template Resolvers(模板可能不存在,或者任何配置的模板解析程式都無法訪問)
3.SpringBoot整合Thymeleaf
Thymeleaf
是一個XML/XHTML/HTML5
模板引擎,可用於Web與非Web環境中的應用開發。Thymeleaf
的主要目標在於提供一種可被瀏覽器正確顯示的、格式良好的模板建立方式,因此也可以用作靜態建模。在Spring Boot中使用Thymeleaf只需在pom中加入Thymeleaf的starter即可。
Thymeleaf官方網站,GitHup(Thymeleaf)
- 修改pom,引入Thymeleaf的starter依賴
1 <!-- SpringBoot整合Thymeleaf --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-thymeleaf</artifactId> 5 </dependency>
預設的Thymeleaf版本為2.x.x.RELEASE版本,這裡推薦使用3.0以上版本。建議在pom中將Thymeleaf的版本修改為3.0.x.RELEASE以上。(網上很多人說需要改,當然我沒有改過,如果你想要更改高版本,可以參考——個人覺得沒必要較真必須改,應當遵循你的專案情況而定,難道開發SpringBoot的人傻嗎?)
1 <properties> 2 <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> 3 <thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version> 4 </properties>
- 修改yml檔案配置基本資訊
(可以不配,SpringBoot預設推薦該模板)
1 Spring: 2 #開啟模板快取(預設值:true) 3 thymeleaf: 4 cache: false 5 # 在呈現效果前檢查模板是否存在. 6 check-template: true 7 # 檢查模板位置是否正確(預設值:true) 8 check-template-location: true 9 # Content-Type的值(預設值:text/html) 10 servlet: 11 content-type: text/html 12 # 開啟MVC Thymeleaf檢視解析(預設值:true) 13 enabled: true 14 # 模板編碼 15 encoding: UTF-8 16 # 要被排除在解析之外的檢視名稱列表 17 # excluded-view-names: 18 # 要運用於模板之上的模板模式。另見StandardTemplate-ModeHandlers(預設值:HTML5) 19 mode: HTML5 20 # 在構建URL時新增到檢視名稱前的字首(模板載入路徑:預設值:classpath:/templates/) 21 prefix: classpath:/templates/ 22 # 在構建URL時新增到檢視名稱後的字尾(預設值:.html) 23 suffix: .html 24 # Thymeleaf模板解析器在解析器鏈中的順序。預設情況下,它排第一位。順序從1開始,只有在定義了額外的TemplateResolver Bean時才需要設定這個屬性。 25 # template-resolver-order: 26 # 可解析的檢視名稱列表 27 # view-names: 28 # -
- 新建模板
1 <!DOCTYPE html> 2 <html xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Insert title here</title> 6 </head> 7 <body> 8 <div th:text="${url}"></div> 9 </body> 10 </html>
在html頁面中引入thymeleaf名稱空間,即,此時在html模板檔案中動態的屬性使用th:名稱空間修飾 。(避免thymeleaf語法報錯,標註警告等問題)
以下簡單瞭解:詳情請參閱博主模板語法筆記。th屬性
html有的屬性,Thymeleaf基本都有,而常用的屬性大概有七八個。其中th屬性執行的優先順序從1~8,數字越低優先順序越高。
-
th:text :設定當前元素的文字內容,相同功能的還有th:utext,兩者的區別在於前者不會轉義html標籤,後者會。優先順序不高:order=7
-
th:value:設定當前元素的value值,類似修改指定屬性的還有th:src,th:href。優先順序不高:order=6
-
th:each:遍歷迴圈元素,和th:text或th:value一起使用。注意該屬性修飾的標籤位置,詳細往後看。優先順序很高:order=2
-
th:if:條件判斷,類似的還有th:unless,th:switch,th:case。優先順序較高:order=3
-
th:insert:程式碼塊引入,類似的還有th:replace,th:include,三者的區別較大,若使用不恰當會破壞html結構,常用於公共程式碼塊提取的場景。優先順序最高:order=1
-
th:fragment:定義程式碼塊,方便被th:insert引用。優先順序最低:order=8
-
th:object:宣告變數,一般和*{}一起配合使用,達到偷懶的效果。優先順序一般:order=4
-
th:attr:修改任意屬性,實際開發中用的較少,因為有豐富的其他th屬性幫忙,類似的還有th:attrappend,th:attrprepend。優先順序一般:order=5
-
- 編寫控制器
1 @Controller 2 public class HtmlController { 3 4 @RequestMapping("/indexHtml") 5 public String indexHtml(Model model) { 6 model.addAttribute("url","XSGE個人網站:http://www.xsge123.com"); 7 System.out.println("ceshi"); 8 return "indexHtml"; 9 } 10 }
- 測試訪問
啟動SpringBoot主程式,單開瀏覽器訪問:http://localhost:8080/indexHtml
常見錯誤:沒有手動重啟伺服器!導致無法解析,錯誤程式碼500,顯示資訊:template might not exist or might not be accessible by any of the configured Template Resolvers(模板可能不存在,或者任何配置的模板解析程式都無法訪問)
附錄
SpingBoot整合JSP,打包問題:兩種總結
1.網上很多說法是,在pom.xml中配置打包地址(這種方法可行)實現如下:
A,修改pom檔案,在外掛中配置JSP資源路徑。
B,修改SpringBoot打包外掛版本為(1.4.2.RELEASE)
C,執行Mavne命令打包
1 <!-- SpringBoot打包外掛 --> 2 <build> 3 <plugins> 4 <plugin> 5 <groupId>org.springframework.boot</groupId> 6 <artifactId>spring-boot-maven-plugin</artifactId> 7 <version>1.4.2.RELEASE</version> 8 </plugin> 9 </plugins> 10 11 <resources> 12 <resource> 13 <directory>src/main/java</directory> 14 <includes> 15 <include>**/**</include> 16 </includes> 17 </resource> 18 <resource> 19 <directory>src/main/resources</directory> 20 <includes> 21 <include>**/**</include> 22 </includes> 23 <filtering>false</filtering> 24 </resource> 25 <!-- 打包時將jsp檔案拷貝到META-INF目錄下--> 26 <resource> 27 <!-- 指定resources外掛處理哪個目錄下的資原始檔 --> 28 <directory>src/main/webapp</directory> 29 <includes> 30 <include>**/**</include> 31 </includes> 32 <!--注意此次必須要放在此目錄下才能被訪問到--> 33 <targetPath>META-INF/resources</targetPath> 34 <filtering>false</filtering> 35 </resource> 36 </resources> 37 </build>
很多人可能都在網上看到過類似的配置,但幾乎沒有明確版本!然而,這種配置方式在SpringBoot版本升級後,官方便提出不推薦使用,在SpringBoot1.4.x版本之後,推薦整合JSP時打包為war包方式,SpringBoot專案整合內建Tomcat外掛,所以我們打包的war檔案,無需考慮安裝伺服器問題,就把它當作一個jar檔案一樣執行即可
Java -jar 檔名.jar/war
2.無需在pom中過多配置,修改打包方式為war即可。
A,修改打包方式為war
B,執行Maven命令打包
C,啟動jar測試訪問
<packaging>war</packaging>
&n