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.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
: 操做數組或集合的工具.每一個類中的具體方法,點擊查看:www.thymeleaf.org/doc/tutoria…
先上效果圖:
IDEA默認是開啓了Thymeleaf 插件支持的,若是不放心須要驗證,請訪問:www.jetbrains.com/help/idea/2…
但僅僅是配置上面的效果,依然是沒法正常使用的,緣由是你要在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="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:github.com/vipstone/sp…
thymeleaf官方文檔 Thymeleaf :www.thymeleaf.org/doc/tutoria…
thymeleaf官方文檔 Spring + Thymeleaf :www.thymeleaf.org/doc/tutoria…