使用Thymeleaf 三大理由: 簡潔漂亮 容易理解 完美支持HTML5 使用瀏覽器直接打開頁面 不新增標簽 只需增強屬性 學習目標 快速掌握Thymeleaf的基本使用:五大基礎語法,常用內置對象 快速查閱 源碼下載:springboot-web-thymeleaf-enhance — Hey ...
使用Thymeleaf 三大理由:
- 簡潔漂亮 容易理解
- 完美支持HTML5 使用瀏覽器直接打開頁面
- 不新增標簽 只需增強屬性
學習目標
- 快速掌握Thymeleaf的基本使用:五大基礎語法,常用內置對象
快速查閱
源碼下載:springboot-web-thymeleaf-enhance
— Hey Man,Don't forget to Star or Fork . —
官方指南: Thymleaf 3.0 官方教程
使用教程
溫馨提示:Thymeleaf 最為顯著的特征是增強屬性,任何屬性都可以通過th:xx 來完成交互,例如th:value最終會覆蓋value屬性。
一、基礎語法
變數表達式 ${}
使用方法:直接使用th:xx = "${}"
獲取對象屬性 。例如:
<form id="userForm">
<input id="id" name="id" th:value="${user.id}"/>
<input id="username" name="username" th:value="${user.username}"/>
<input id="password" name="password" th:value="${user.password}"/>
</form>
<div th:text="hello"></div>
<div th:text="${user.username}"></div>
選擇變數表達式 *{}
使用方法:首先通過th:object
獲取對象,然後使用th:xx = "*{}"
獲取對象屬性。
這種簡寫風格極為清爽,推薦大家在實際項目中使用。 例如:
<form id="userForm" th:object="${user}">
<input id="id" name="id" th:value="*{id}"/>
<input id="username" name="username" th:value="*{username}"/>
<input id="password" name="password" th:value="*{password}"/>
</form>
鏈接表達式 @{}
使用方法:通過鏈接表達式@{}
直接拿到應用路徑,然後拼接靜態資源路徑。例如:
<script th:src="@{/webjars/jquery/jquery.js}"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css">
片段表達式 ~{}
片段表達式是Thymeleaf的特色之一,細粒度可以達到標簽級別,這是JSP無法做到的。
片段表達式擁有三種語法:
~{ viewName } 表示引入完整頁面
~{ viewName ::selector} 表示在指定頁面尋找片段 其中selector可為片段名、jquery選擇器等
~{ ::selector} 表示在當前頁尋找
使用方法:首先通過th:fragment
定製片段 ,然後通過th:replace
填寫片段路徑和片段名。例如:
<!-- /views/common/head.html-->
<head th:fragment="static">
<script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
</head>
<!-- /views/your.html -->
<div th:replace="~{common/head::static}"></div>
在實際使用中,我們往往使用更簡潔的表達,去掉表達式外殼直接填寫片段名。例如:
<!-- your.html -->
<div th:replace="common/head::static"></div>
值得註意的是,使用替換路徑th:replace
開頭請勿添加斜杠,避免部署運行的時候出現路徑報錯。(因為預設拼接的路徑為spring.thymeleaf.prefix = classpath:/templates/
)
消息表達式
即通常的國際化屬性:#{msg}
用於獲取國際化語言翻譯值。例如:
<title th:text="#{user.title}"></title>
其它表達式
在基礎語法中,預設支持字元串連接、數學運算、布爾邏輯和三目運算等。例如:
<input name="name" th:value="${'I am '+(user.name!=null?user.name:'NoBody')}"/>
二、內置對象
官方文檔: 附錄A: Thymeleaf 3.0 基礎對象
官方文檔: 附錄B: Thymeleaf 3.0 工具類
七大基礎對象:
${#ctx}
上下文對象,可用於獲取其它內置對象。${#vars}
: 上下文變數。${#locale}
:上下文區域設置。${#request}
: HttpServletRequest對象。${#response}
: HttpServletResponse對象。${#session}
: HttpSession對象。${#servletContext}
: ServletContext對象。
常用的工具類:
#strings
:字元串工具類#lists
:List 工具類#arrays
:數組工具類#sets
:Set 工具類#maps
:常用Map方法。#objects
:一般對象類,通常用來判斷非空#bools
:常用的布爾方法。#execInfo
:獲取頁面模板的處理信息。#messages
:在變數表達式中獲取外部消息的方法,與使用#{...}語法獲取的方法相同。#uris
:轉義部分URL / URI的方法。#conversions
:用於執行已配置的轉換服務的方法。#dates
:時間操作和時間格式化等。#calendars
:用於更複雜時間的格式化。#numbers
:格式化數字對象的方法。#aggregates
:在數組或集合上創建聚合的方法。#ids
:處理可能重覆的id屬性的方法。
三、迭代迴圈
想要遍歷List
集合很簡單,配合th:each
即可快速完成迭代。例如遍歷用戶列表:
<div th:each="user:${userList}">
賬號:<input th:value="${user.username}"/>
密碼:<input th:value="${user.password}"/>
</div>
在集合的迭代過程還可以獲取狀態變數,只需在變數後面指定狀態變數名即可,狀態變數可用於獲取集合的下標/序號、總數、是否為單數/偶數行、是否為第一個/最後一個。例如:
<div th:each="user,stat:${userList}" th:class="${stat.even}?'even':'odd'">
下標:<input th:value="${stat.index}"/>
序號:<input th:value="${stat.count}"/>
賬號:<input th:value="${user.username}"/>
密碼:<input th:value="${user.password}"/>
</div>
如果預設狀態變數名,則迭代器會預設幫我們生成以變數名開頭的狀態變數 xxStat
, 例如:
<div th:each="user:${userList}" th:class="${userStat.even}?'even':'odd'">
下標:<input th:value="${userStat.index}"/>
序號:<input th:value="${userStat.count}"/>
賬號:<input th:value="${user.username}"/>
密碼:<input th:value="${user.password}"/>
</div>
四、條件判斷
條件判斷通常用於動態頁面的初始化,例如:
<div th:if="${userList}">
<div>的確存在..</div>
</div>
如果想取反則使用unless 例如:
<div th:unless="${userList}">
<div>不存在..</div>
</div>
五、日期格式化
使用預設的日期格式(toString方法) 並不是我們預期的格式:Mon Dec 03 23:16:50 CST 2018
<input type="text" th:value="${user.createTime}"/>
此時可以通過時間工具類#dates
來對日期進行格式化:2018-12-03 23:16:50
<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"/>
六、內聯寫法
- (1)為什麼要使用內聯寫法?·答:因為 JS無法獲取服務端返回的變數。
- (2)如何使用內聯表達式?答:標準格式為:
[[${xx}]]
,可以讀取服務端變數,也可以調用內置對象的方法。例如獲取用戶變數和應用路徑:
<script th:inline="javascript">
var user = [[${user}]];`
var APP_PATH = [[${#request.getContextPath()}]];
var LANG_COUNTRY = [[${#locale.getLanguage()+'_'+#locale.getCountry()}]];
</script>
- (3)標簽引入的JS裡面能使用內聯表達式嗎?答:不能!內聯表達式僅在頁面生效,因為
Thymeleaf
只負責解析一級視圖,不能識別外部標簽JS裡面的表達式。
七、國際化
需要瞭解更多關於國際化的精彩描述請前往 SpringBoot 快速實現國際化i18n 。
例如在國際化文件中編寫了user.title這個鍵值,然後使用#{}
讀取這個KEY即可獲取翻譯。
<title th:text="#{user.title}">用戶登陸</title>
八、詳細教程
======== 有了上述基礎後 下麵正式開始Thymeleaf 的詳細教程 ==============
首先通過Spring Initializr創建項目,
然後在POM文件引入web 、thymeleaf
等依賴
<dependencies>
<dependency><!--Web相關依賴-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><!--頁面模板依賴-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency><!--熱部署依賴-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
然後在src/main/resources/application.yml
配置頁面路徑:
spring:
thymeleaf:
cache: false #關閉緩存
prefix: classpath:/views/ #調整頁面路徑
接著在src/main/java/com/hehe/web/UserController
獲取用戶信息:
@RestController
public class UserController {
private List<User> userList = new ArrayList<>();
{
userList.add(new User("1", "socks", "123456", new Date()));
userList.add(new User("2", "admin", "111111", new Date()));
userList.add(new User("3", "jacks", "222222", null));
}
@GetMapping("/")
public ModelAndView index() {
return new ModelAndView("user/user", "userList", userList);
}
}
public class User {
private String id;
private String username;
private String password;
private Date createTime;
//請讀者自行補充 構造器和 get/set方法..
}
開始編寫公共頁面:src/main/resources/views/common/head.html
,其中static
為頁面片段:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!--聲明static為頁面片段名稱-->
<head th:fragment="static">
<link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css"/>
<script th:src="@{/webjars/jquery/jquery.js}"></script>
</head>
</html>
接著編寫用戶列表頁:src/main/resources/views/user/user.html
配合th:each
顯示用戶列表信息。
使用說明:這裡 th:replace="common/head::static"
表示將引用${spring.thymeleaf.prefix}/common/head.html
的static
頁面片段,值得註意的是由於替換路徑預設會拼接首碼路徑,所以開頭切勿在添加斜杠,否則在打包成JAR部署運行時將提示報Templates not found...
。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title th:text="用戶信息">User</title>
<!--預設拼接首碼路徑,開頭請勿再添加斜杠,防止部署運行報錯!-->
<script th:replace="common/head::static"></script>
</head>
<body>
<div th:each="user,userStat:${userList}" th:class="${userStat.even}?'even':'odd'">
序號:<input type="text" th:value="${userStat.count}"/>
賬號:<input type="text" th:value="${user.username}"/>
密碼:<input type="password" th:value="${user.password}"/>
時間:<input type="text" th:value="${user.createTime}"/>
時間:<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"/>
</div>
<script th:inline="javascript">
//通過內聯表達式獲取用戶信息
var userList = [[${userList}]];
console.log(userList)
</script>
</body>
</html>
然後編寫單個用戶頁面:
至此大功告成,然後快速啟動項目,如圖所示:
快速啟動項目
然後訪問用戶列表: http://localhost:8080,如圖所示
然後訪問單個用戶: http://localhost:8080/user/1,如圖所示: