Thymeleaf是一種Java XML / XHTML / HTML5模板引擎,能夠在Web和非Web環境中使用。它更適合在基於MVC的Web應用程序的視圖層提供XHTML / HTML5,但即便在脫機環境中,它也能夠處理任何XML文件。它提供了完整的Spring Framework集成。php
關於Spring推薦Thymeleaf的這種說法,我在Spring官方文檔並無看到具體的說明,只是在和JSP比較的時候,說了JSP和Thymeleaf對比JSP的一些不足,而Thymeleaf只是做爲其餘模板引擎的一種表明。html
做爲一款優秀的模板引擎,除了易用性、活躍的社區、健康快速的發展外,還有很是重要的一點就是性能了,那Thymeleaf 3 和 FreeMaker 的性能對比是怎麼樣的,後續文章會陸續更新。java
Thymeleaf的使用是由兩部分組成的:標籤 + 表達式,標籤是Thymeleaf的語法結構,而表達式就是語法裏的內容實現。node
經過標籤 + 表達式,讓數據和模板結合,最終轉換成html代碼,返回給用戶。git
Thymeleaf基礎使用分爲三部分:github
HTML代碼:golang
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <span th:text="${name}"></span> </body> </html>
Java代碼:web
@RequestMapping("/") public ModelAndView index() { ModelAndView modelAndView = new ModelAndView("/index"); modelAndView.addObject("name", "老王"); return modelAndView; }
最終效果: 老王
spring
使用"th:text"是對內容的原樣輸出,使用「th:utext」能夠進行html標籤輸出。express
Java代碼:
@RequestMapping("/eat") public ModelAndView eat() { ModelAndView modelAndView = new ModelAndView("/cat"); modelAndView.addObject("data", "<span style='color:red'>老王是吃貨</span>"); return modelAndView; }
HTML代碼:
<h4 th:text="'th:text '+${data}"></h4> <h4 th:utext="'th:utext '+${data}"></h4>
展現效果:
<span th:if="${age > 18}"> 成年 </span> <span th:unless="${age > 18}"> 未成年 </span>
th:if爲知足條件的業務處理,th:unless正好相反,是除去的意思。
<div th:switch="${age}"> <span th:case="18">18歲</span> <span th:case="19">19歲</span> <spa th:case="*">其餘</spa> </div>
注意: 默認選項使用th:case="*"
指定。
HTML代碼:
<div th:each="name,item:${names}"> <span th:text="${item.count}"></span> <span th:text="${name}"></span> </div>
Java代碼:
@RequestMapping("/") public ModelAndView index() { ArrayList<String> names = new ArrayList<>(); names.add("java"); names.add("golang"); names.add("nodejs"); ModelAndView modelAndView = new ModelAndView("/index"); modelAndView.addObject("names",names); return modelAndView; }
訪問效果以下:
其中item爲每行的詳細值,key值以下:
footer.html頁面代碼:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <div th:fragment="copyright"> © 著做權歸 老王 全部 </div> <div th:fragment="about"> 關於 </div> <div th:fragment="links"> CCTV </div> </body> </html>
聲明瞭兩個代碼片斷,copyright和about。
cat.html頁面代碼:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <div th:replace="footer :: copyright"></div> <div th:insert="footer :: about"></div> <div th:include="footer :: links"></div> </body> </html>
其中第一個div引用了footer.html 的 copyright 代碼片斷,第二個div引用了 footer.html 的 about 代碼片斷。
雙冒號的理解: 其中使用「::」雙冒號來完成對頁面片斷的引用,有點像php裏面的語法,使用雙冒號來表示對類的靜態屬性和方法進行直接引用。
執行效果以下圖:
總結: 能夠很清晰的看出th:insert、th:replace、th:include之間的區別,在因而否保留本身的主標籤,th:include 在3.0以後已經不推薦使用了,可使用th:replace標籤替代。
使用fragment咱們是能夠在html代碼中傳參的,好比咱們定義了一個top.html其中有一個「歡迎XXX」的提示,而這我的名XXX就是須要動態傳遞的,這樣咱們能夠最大程度的完成代碼的複用,這個時候就是一個很好的使用場景,咱們須要這樣作。
頁面main.html代碼:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" > <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <div th:replace="footer :: webcome('老王')"></div> </body> </html>
頁面top.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" > <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <div th:fragment="webcome(about)"> <span th:text="'歡迎:'+${about}"></span> </div> </body> </html>
最終的效果:
頁面代碼:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" > <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <div th:with="sum=4-2"> <span th:text="${sum}"></span> </div> </body> </html>
頁面輸出結果:2
th:remove用於html代碼的刪除,th:remove值有五個:
示例index.html代碼以下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <div id="all" th:remove="all"> <span>all</span> <span>1</span> </div> <div id="body" th:remove="body"> <span>body</span> <span>2</span> </div> <div id="tag" th:remove="tag"> <span>tag</span> <span>3</span> </div> <div id="all-but-first" th:remove="all-but-first"> <span>all-but-first</span> <span>4</span> </div> <div id="none" th:remove="none"> <span>none</span> <span>5</span> </div> </body> </html>
最終展現效果以下:
<div th:style="'color:'+${skinColor}">
<input type="button" value=" Click " th:onclick="'onsub()'">
<a th:href="${myhref}"></a>
<input th:value="${user.name}" />
<img th:src="${img}" />
<form th:action="@{/suburl}">
<form id="${fromid}">
<img th:attr="src=@{/img/stone.jpg},alt=${alt}" />
<div th:object="${user}">
變量表達式:${...}
選擇變量表達式:*{...}
消息表達式:#{...}
連接表達式:@{...}
片斷表達:~{...}
文字:'one text', 'Another one!',…
數字文字:0, 34, 3.0, 12.3,…
布爾文字:true, false
NULL文字:null
文字標記:one, sometext, main,…
字符串拼接:+
字面替換:|The name is ${name}|
二進制運算符:+, -, *, /, %
減號(一元運算符):-
二進制運算符:and, or
布爾否認(一元運算符):!, false
比較值:>, <, >=, <=
相等判斷: ==, !=
若是-而後:(if) ? (then)
若是-而後-不然:(if) ? (then) : (else)
違約:(value) ?: (defaultvalue)
全部以上這些表達式均可以組合和嵌套,例如:
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
變量表達式的使用,咱們前面的代碼已經見到了,$是咱們日常開發中最經常使用的表達式,用於把後臺Java類的動態數據,映射到頁面,例如:
Java代碼:
public ModelAndView index() { ModelAndView modelAndView = new ModelAndView("/cat"); modelAndView.addObject("data", "我是老王"); return modelAndView; }
HTML代碼:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <span th:text="${data}"></span> </body> </html>
最終效果:
選擇表達式至關於選擇了一個對象,在使用的時候不在須要這個對象的前綴,直接使用屬性的key進行內容展現,代碼以下:
<div th:object="${goods}"> <span th:text="${goods.name}"></span> <span th:text="*{price}"></span> <span th:text="${#dates.format(goods.createTime, 'yyyy-MM-dd HH:mm:ss')}"></span> </div>
最終效果:
iMac 7999.0 2018-08-10 14:03:51
總結: *{price} = ${goods.price}只是省去了「goods.」前綴,效果都是同樣的。
用於轉換url,代碼以下:
<a th:href="@{/footer(id=666,name=laowang)}">連接</a>
最終呈現的效果:
<a href="/footer?id=666&name=laowang">連接</a>
連接表達式,能夠傳遞參數,用逗號分隔。
服務器根相對路徑:@{~/path/to/something}
文本操做分爲兩個:文本拼加、文本替換
文本拼加:
<span th:text="'我叫'+${name}"></span>
文本替換:
文本替換的語法:|內容${tag}|
<span th:text="|我叫${name},是一名開發工程師。|"></span>
<p th:text="${val}">...</p> <p th:text="${{val}}">...</p>
結果:
<p>1234567890</p> <p>1,234,567,890</p>
雖然標準的標籤幾乎能夠知足全部的業務場景,但某些狀況咱們更喜歡直接寫入HTML文本,例如:
<p>Hello, [[${name}]]</p>
嵌入文本有兩種寫法「[[...]]」和「[(...)]」,分別的做用就像th:text 和 th:utext 同樣,例如:
<p> [[${name}]] </p> <p> [(${name})] </p>
看到的效果是這樣的:
表達式裏面的對象能夠幫助咱們處理要展現的內容,好比表達式的工具類dates能夠格式化時間,這些內置類的熟練使用,可讓咱們使用Thymeleaf的效率提升不少。
#ctx
: 操做當前上下文.#vars:
操做上下文變量.#request
: (僅適用於Web項目) HttpServletRequest
對象.#response
: (僅適用於Web項目) HttpServletResponse
對象.#session
: (僅適用於Web項目) HttpSession
對象.#servletContext
: (僅適用於Web項目) ServletContext
對象.#execInfo
: 操做模板的工具類,包含了一些模板信息,好比:${#execInfo.templateName}
.#uris
: url處理的工具#conversions
: methods for executing the configured conversion service (if any).#dates
: 方法來源於 java.util.Date
對象,用於處理時間,好比:格式化.#calendars
: 相似於 #dates
, 可是來自於 java.util.Calendar
對象.#numbers
: 用於格式化數字.#strings
: methods for String
objects: contains, startsWith, prepending/appending, etc.#objects
: 普通的object對象方法.#bools
: 判斷bool類型的工具.#arrays
: 數組操做工具.#lists
: 列表操做數據.#sets
: Set操做工具.#maps
: Map操做工具.#aggregates
: 操做數組或集合的工具.每一個類中的具體方法,點擊查看:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expression-utility-objects
先上效果圖:
IDEA默認是開啓了Thymeleaf 插件支持的,若是不放心須要驗證,請訪問:https://www.jetbrains.com/help/idea/2018.2/thymeleaf.html
但僅僅是配置上面的效果,依然是沒法正常使用的,緣由是你要在html中聲明 Thymeleaf 命名空間 xmlns:th="http://www.thymeleaf.org"
,完整代碼以下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2 th:text="${hi}"></h2> </body> </html>
其中關鍵的代碼是:
xmlns:th="http://www.thymeleaf.org"
這樣當你在代碼輸入「th:」的時候就會看到 Thymeleaf 的全部標籤了。
在正式集成Thymeleaf引擎以前,先來看下目錄結構如圖:
除去包名,咱們來解釋一下這些目錄表明的含義:
接下來咱們具體分別來看具體的步驟。
<!--thymeleaf模板--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
# 啓用緩存:建議生產開啓 spring.thymeleaf.cache=false # 建議模版是否存在 spring.thymeleaf.check-template-location=true # Content-Type 值 spring.thymeleaf.servlet.content-type=text/html # 是否啓用 spring.thymeleaf.enabled=true # 模版編碼 spring.thymeleaf.encoding=utf-8 # 應該從解析中排除的視圖名稱列表(用逗號分隔) spring.thymeleaf.excluded-view-names= # 模版模式 spring.thymeleaf.mode=HTML5 # 模版存放路徑 spring.thymeleaf.prefix=classpath:/templates/ # 模版後綴 spring.thymeleaf.suffix=.html
配置項 | 類型 | 默認值 | 建議值 | 說明 |
---|---|---|---|---|
spring.thymeleaf.enabled | bool | true | 默認 | 是否啓用 |
spring.thymeleaf.mode | String | HTML | 默認 | 模板類型,能夠設置爲HTML5 |
spring.thymeleaf.cache | bool | true | 默認 | 是否啓用緩存,生成環境建議設置爲true |
spring.thymeleaf.prefix | String | classpath:/templates/ | 默認 | 模版存放路徑 |
spring.thymeleaf.suffix | String | .html | 默認 | 模版後綴 |
spring.thymeleaf.servlet.content-type | String | text/html | 默認 | Content-Type 值 |
spring.thymeleaf.encoding | String | - | utf-8 | 模版編碼 |
咱們在controller文件夾建立index.java,代碼以下:
package com.hello.springboot.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/") public class Index { @RequestMapping("/") public ModelAndView index() { ModelAndView modelAndView = new ModelAndView("/index"); modelAndView.addObject("name", "王磊的博客"); return modelAndView; } }
關鍵代碼解讀:
咱們在resources/templates下建立index.html,代碼以下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>王磊的博客</title> </head> <body> <span th:text="${name}"></span> </body> </html>
啓動調試,在瀏覽器輸入:http://localhost:8080/
效果以下:
相關代碼GitHub:https://github.com/vipstone/springboot-example.git
thymeleaf官方文檔 Thymeleaf :https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
thymeleaf官方文檔 Spring + Thymeleaf :https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html