一,Thymeleaf 簡介
Thymeleaf 是一個跟 Velocity、FreeMarker 類似的模板引擎,它可以完全替代 JSP 。相較與其他的模板引擎,它有如下三個極吸引人的特點:
1,Thymeleaf 在有網絡和無網絡的環境下皆可運行,即它可以讓美工在瀏覽器查看頁面的靜態效果,也可以讓程序員在服務器查看帶數據的動態頁面效果。這是由於它支持 html 原型,然后在 html 標簽里增加額外的屬性來達到模板+數據的展示方式。瀏覽器解釋 html 時會忽略未定義的標簽屬性,所以 thymeleaf 的模板可以靜態地運行;當有數據返回到頁面時,Thymeleaf 標簽會動態地替換掉靜態內容,使頁面動態顯示。
2,Thymeleaf 開箱即用的特性。它提供標准和spring標准兩種方言,可以直接套用模板實現JSTL、 OGNL表達式效果,避免每天套模板、該jstl、改標簽的困擾。同時開發人員也可以擴展和創建自定義的方言。
3.,Thymeleaf 提供spring標准方言和一個與 SpringMVC 完美集成的可選模塊,可以快速的實現表單綁定、屬性編輯器、國際化等功能。
二,Hello Thymeleaf實例
1,創建Maven項目
具體步驟參照:Eclipse中創建Maven Web項目
2,添加Spring的依賴
具體步驟參考:Maven創建Spring MVC項目
3,修改pom.xml文件,加入Thymeleaf
<!-- thymeleaf模板引擎 --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>2.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring4</artifactId> <version>2.1.4.RELEASE</version> </dependency>
4,在Spring MVC配置文件中添加thymeleaf視圖解釋器
<!-- 視圖解析器 --> <!-- 使用thymeleaf解析 --> <bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".html" /> <property name="templateMode" value="HTML5" /> <!-- 緩存--> <property name="cacheable" value="false"/> </bean> <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"> <property name="templateResolver" ref="templateResolver" /> </bean> <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver"> <property name="templateEngine" ref="templateEngine" /> <!--解決中文亂碼--> <property name="characterEncoding" value="UTF-8"/> </bean>
關閉Thymeleaf頁面的緩存,可以讓對頁面的改動及時反映到視圖中。
5,創建一個頁面
html頁面標簽中引入如下:
<html xmlns:th="http://www.thymeleaf.org">
具體html頁面如下:
<!DOCTYPE html> <html lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>index</title> </head> <body> Hello Thymeleaf! </body> </html>
6,創建一個Controller
@Controller @RequestMapping("/index") public class IndexController { @RequestMapping("returnString") public String returnString(){ return "index"; } }
7,運行項目訪問IndexController
三,頁面參數獲取/回顯
1,創建一個pojo
public class Person { private int id; private String name; private String addrs; public Person(int id, String name, String addrs) { super(); this.id = id; this.name = name; this.addrs = addrs; } public Person() { super(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddrs() { return addrs; } public void setAddrs(String addrs) { this.addrs = addrs; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", addrs=" + addrs + "]"; } }
2,創建提交表單頁面person.html
<!DOCTYPE html> <html lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>person</title> <link href="css/bootstrap.css" rel="stylesheet"/> <script src="js/jquery-3.2.1.js"></script> <script src="js/bootstrap.js"></script> </head> <body> <form th:action="@{savePerson}" th:method="post"> <div class="form-group"> <label class="col-sm-2 control-label">id</label> <div class="col-sm-10"> <input type="text" class="form-control" name="id" placeholder="id" /> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">名稱</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" placeholder="name" /> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">地址</label> <div class="col-sm-10"> <input type="text" class="form-control" name="addrs" placeholder="addrs" /> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> </body> </html>
解釋:
th:action屬性 |
表示其值代替靜態頁面的action的值。等價action='/savePerson'。 |
th:method屬性 |
表示其值將代替靜態頁面的method的值。等價method='post'。 |
3,創建回顯頁面return.html
<!DOCTYPE html> <html lang="zh-CN" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>return</title> <link href="css/bootstrap.css" rel="stylesheet"/> <script src="js/jquery-3.2.1.js"></script> <script src="js/bootstrap.js"></script> </head> <body> <!-- from表單獲取提交過來的數據 --> <h3>from表單獲取提交過來的數據</h3> <form th:action="@{savePerson}" th:method="post" th:object="${person}"> <div class="form-group"> <label class="col-sm-2 control-label">id</label> <div class="col-sm-10"> <input type="text" class="form-control" name="id" placeholder="id" th:value="*{id}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">名稱</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" placeholder="name" th:value="*{name}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">地址</label> <div class="col-sm-10"> <input type="text" class="form-control" name="addrs" placeholder="addrs" th:value="*{addrs}"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form> <!-- 表格獲取提交過來的數據 --> <h3>表格獲取提交過來的數據 </h3> <table class="table" th:object="${person}"> <tr> <td>id</td> <td>name</td> <td>addrs</td> </tr> <tr> <td th:text="${person.id}"></td> <td th:text="${person.name}"></td> <td th:text="${person.addrs}"></td> </tr> </table> </body> </html>
解釋:
th:object屬性 |
表示有一個屬性名為"person"的Java bean傳遞到頁面上來。可以通過表達式*{fieldName}才能取得其值。 |
th:value屬性 |
表示取得Person實例中的屬性值,也就是通過調用Java bean的get方法獲得。等價於標簽value='xxx' |
th:text屬性 |
文本顯示。等價於標簽text='xxx' |
4,創建PersonController
@Controller public class PersonController { @RequestMapping public String returnString(){ return "person"; } @RequestMapping("/savePerson") public String savePerson(Model Model ,Person person){ Model.addAttribute("person", person); return "return"; } }
運行訪問:http://localhost:8081/Thymeleaf/,點擊提交
運行結果:
四,基本表達式
1,${}
變量表達式(美元表達式),用於訪問容器上下文環境中的數據,功能與jstl中${}的相同。
<td th:text="${person.id}"></td> <td th:text="${person.name}"></td> <td th:text="${person.addrs}"></td>
2,*{}
選擇表達式(星號表達式),獲取選定對象里的數據域(th:object屬性用於綁定對象)。
選擇表達式與變量表達式的區別:
選擇表達式計算的是選定的對象,而不是整個環境變量映射。也就是:只要是沒有選擇的對象,選擇表達式與變量表達式的語法是完全一樣的。
<!-- from表單獲取提交過來的數據 --> <h3>from表單獲取提交過來的數據</h3> <form th:action="@{savePerson}" th:method="post" th:object="${person}"> <div class="form-group"> <label class="col-sm-2 control-label">id</label> <div class="col-sm-10"> <input type="text" class="form-control" name="id" placeholder="id" th:value="*{id}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">名稱</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" placeholder="name" th:value="*{name}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">地址</label> <div class="col-sm-10"> <input type="text" class="form-control" name="addrs" placeholder="addrs" th:value="*{addrs}"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form>
3,#{}
沒明白怎么使用!自己測試不出來。希望看見的大佬能指點迷津。
4,@{}
超鏈接url表達式。
<script th:src="@{/js/jquery/jquery.js}"></script>
五,常用屬性
1,th:action
定義后台控制器路徑,類似<form>標簽的action屬性。
2,th:each
對象遍歷,功能類似jstl中的<c:forEach>標簽
Controller
@RequestMapping("/listPerson") public String listPerson(Model Model){ List<Person> list = new ArrayList<Person>(); list.add(new Person(1, "Zender", "Shanghai")); list.add(new Person(2, "Zender2", "Shanghai2")); list.add(new Person(3, "Zender3", "Shanghai3")); Model.addAttribute("listPerson", list); return "listPerson"; }
頁面
<head> <meta charset="UTF-8"/> <title>listPerson</title> <link th:href="@{/css/bootstrap.css}" rel="stylesheet"/> <script th:src="@{/js/jquery-3.2.1.js}"></script> <script th:src="@{/js/bootstrap.js}"></script> </head> <body> <h3>each循環</h3> <table class="table"> <tr> <td>id</td> <td>name</td> <td>addrs</td> </tr> <tbody th:each="person,personStat:${listPerson}"> <tr> <td th:text="${person.id}"></td> <td th:text="${person.name}"></td> <td th:text="${person.addrs}"></td> </tr> </tbody> </table> </body> </html>
personStat稱作狀態變量,屬性有:
index |
當前迭代對象的index(從0開始計算)。 |
count |
當前迭代對象的index(從1開始計算)。 |
size |
被迭代對象的大小。 |
current |
當前迭代變量。 |
even/odd |
布爾值,當前循環是否是偶數/奇數(從0開始計算)。 |
first |
布爾值,當前循環是否是第一個。 |
last |
布爾值,當前循環是否是最后一個。 |
3,th:field
常用於表單字段綁定。通常與th:object一起使用。 屬性綁定、集合綁定。
Controller
@RequestMapping("/person") public String returnString(){ return "person"; } @RequestMapping("/savePerson") public String savePerson(Model Model ,Person person){ Model.addAttribute("person", person); return "return"; }
表單頁面
<form th:action="@{savePerson}" th:method="post"> <div class="form-group"> <label class="col-sm-2 control-label">id</label> <div class="col-sm-10"> <input type="text" class="form-control" name="id" placeholder="id" /> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">名稱</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" placeholder="name" /> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">地址</label> <div class="col-sm-10"> <input type="text" class="form-control" name="addrs" placeholder="addrs" /> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form>
回顯頁面
<!-- from表單獲取提交過來的數據 --> <h3>from表單獲取提交過來的數據</h3> <form th:action="@{savePerson}" th:method="post" th:object="${person}"> <div class="form-group"> <label class="col-sm-2 control-label">id</label> <div class="col-sm-10"> <input type="text" class="form-control" name="id" placeholder="id" th:field="*{id}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">名稱</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" placeholder="name" th:field="*{name}"/> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">地址</label> <div class="col-sm-10"> <input type="text" class="form-control" name="addrs" placeholder="addrs" th:field="*{addrs}"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </div> </form>
4,th:href
定義超鏈接。
<link th:href="@{/css/bootstrap.css}" rel="stylesheet"/>
5,th:id
id聲明,類似html標簽中的id屬性。
<div th:id="ids"></div>
6,th:if,th:unless
th:if條件判斷,th:if中條件成立時才顯示。
th:unless於th:if恰好相反,表達式中的條件不成立,才會顯示其內容。
<div th:if="${person.id} == 0">123</div>
7,th:include,th:replace和th:fragment
th:fragment |
布局標簽,定義一個代碼片段,方便其它地方引用。常與th:include,th:replace一起使用。 |
th:include |
布局標簽,替換內容到引入的文件。 |
th:replace |
布局標簽,替換整個標簽到引入的文件。 |
模板文件footer.html:
<div th:fragment="footer" > Copyright ©2018 Zender </div> <div th:fragment="head" > 頭部 Zender </div>
頁面index.html
<body> <div th:include="../templates/footer :: head"></div> Hello Thymeleaf! <div th:include="../templates/footer :: footer"></div> </body>
文件路徑
訪問
8,th:src
用於外部資源引入,類似於<script>標簽的src屬性,常與@{}一起使用。
<script th:src="@{/js/jquery-3.2.1.js}"></script>
9,th:text
文本顯示。
<td class="text" th:text="${username}" ></td>
10,th:value
用於標簽復制,類似<option>標簽的value屬性。
<input type="text" class="form-control" name="name" placeholder="name" th:value="*{name}"/>
11,th:switch
默認屬性default可以用*表示。
<div th:switch="${user.role}"> <p th:case="'admin'">User is an administrator</p> <p th:case="#{roles.manager}">User is a manager</p> <p th:case="*">User is some other thing</p> </div>
常用屬性表格:
關鍵字 |
功能介紹 |
案例 |
th:id |
替換id |
<input th:id="'xxx' + ${collect.id}"/> |
th:text |
文本替換 |
<p th:text="${collect.description}">description</p> |
th:utext |
支持html的文本替換 |
<p th:utext="${htmlcontent}">conten</p> |
th:object |
替換對象 |
<div th:object="${session.user}"> |
th:value |
屬性賦值 |
<input th:value="${user.name}" /> |
th:with |
變量賦值運算 |
<div th:with="isEven=${prodStat.count}%2==0"></div> |
th:style |
設置樣式 |
th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''" |
th:onclick |
點擊事件 |
th:onclick="'getCollect()'" |
th:each |
屬性賦值 |
tr th:each="user,userStat:${users}"> |
th:if |
判斷條件 |
<a th:if="${userId == collect.userId}" > |
th:unless |
和th:if判斷相反 |
<a th:href="@{/login}" th:unless=${session.user != null}>Login</a> |
th:href |
鏈接地址 |
<a th:href="@{/login}" th:unless=${session.user != null}>Login</a> /> |
th:switch |
多路選擇 配合th:case 使用 |
<div th:switch="${user.role}"> |
th:case |
th:switch的一個分支 |
<p th:case="'admin'">User is an administrator</p> |
th:fragment |
布局標簽,定義一個代碼片段,方便其它地方引用 |
<div th:fragment="alert"> |
th:include |
布局標簽,替換內容到引入的文件 |
<head th:include="layout :: htmlhead" th:with="title='xx'"></head> /> |
th:replace |
布局標簽,替換整個標簽到引入的文件 |
<div th:replace="fragments/header :: title"></div> |
th:selected |
selected選擇框 選中 |
th:selected="(${xxx.id} == ${configObj.dd})" |
th:src |
圖片類地址引入 |
<img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" /> |
th:inline |
定義js腳本可以使用變量 |
<script type="text/javascript" th:inline="javascript"> |
th:action |
表單提交的地址 |
<form action="subscribe.html" th:action="@{/subscribe}"> |
th:remove |
刪除某個屬性 |
<tr th:remove="all"> 1.all:刪除包含標簽和所有的孩子。2.body:不包含標記刪除,但刪除其所有的孩子。3.tag:包含標記的刪除,但不刪除它的孩子。4.all-but-first:刪除所有包含標簽的孩子,除了第一個。5.none:什么也不做。這個值是有用的動態評估。 |
th:attr |
設置標簽屬性,多個屬性可以用逗號分隔 |
比如 th:attr="src=@{/image/aa.jpg},title=#{logo}",此標簽不太優雅,一般用的比較少。 |