轉(zhuǎn)載學(xué)習(xí)用的皆串,原網(wǎng)站https://www.cnblogs.com/msi-chen/p/10974009.html
目錄
Thymeleaf
官網(wǎng)部分翻譯:反正就是各種好
Thymeleaf是用來(lái)開(kāi)發(fā)Web和獨(dú)立環(huán)境項(xiàng)目的服務(wù)器端的Java模版引擎
Spring官方支持的服務(wù)的渲染模板中,并不包含jsp。而是Thymeleaf和Freemarker等,而Thymeleaf與SpringMVC的視圖技術(shù)遏片,及SpringBoot的自動(dòng)化配置集成非常完美白热,幾乎沒(méi)有任何成本设联,你只用關(guān)注Thymeleaf的語(yǔ)法即可。
Thymeleaf的特點(diǎn)
動(dòng)靜結(jié)合:Thymeleaf 在有網(wǎng)絡(luò)和無(wú)網(wǎng)絡(luò)的環(huán)境下皆可運(yùn)行,即它可以讓美工在瀏覽器查看頁(yè)面的靜態(tài)效果煌恢,也可以讓程序員在服務(wù)器查看帶數(shù)據(jù)的動(dòng)態(tài)頁(yè)面效果二汛。這是由于它支持 html 原型竟宋,然后在 html 標(biāo)簽里增加額外的屬性來(lái)達(dá)到模板+數(shù)據(jù)的展示方式。瀏覽器解釋 html 時(shí)會(huì)忽略未定義的標(biāo)簽屬性躬窜,所以 thymeleaf 的模板可以靜態(tài)地運(yùn)行;當(dāng)有數(shù)據(jù)返回到頁(yè)面時(shí)炕置,Thymeleaf 標(biāo)簽會(huì)動(dòng)態(tài)地替換掉靜態(tài)內(nèi)容荣挨,使頁(yè)面動(dòng)態(tài)顯示。
開(kāi)箱即用:它提供標(biāo)準(zhǔn)和spring標(biāo)準(zhǔn)兩種方言朴摊,可以直接套用模板實(shí)現(xiàn)JSTL默垄、 OGNL表達(dá)式效果,避免每天套模板甚纲、該jstl口锭、改標(biāo)簽的困擾。同時(shí)開(kāi)發(fā)人員也可以擴(kuò)展和創(chuàng)建自定義的方言贩疙。
多方言支持:Thymeleaf 提供spring標(biāo)準(zhǔn)方言和一個(gè)與 SpringMVC 完美集成的可選模塊讹弯,可以快速的實(shí)現(xiàn)表單綁定、屬性編輯器这溅、國(guó)際化等功能组民。
與SpringBoot完美整合,SpringBoot提供了Thymeleaf的默認(rèn)配置悲靴,并且為T(mén)hymeleaf設(shè)置了視圖解析器臭胜,我們可以像以前操作jsp一樣來(lái)操作Thymeleaf。代碼幾乎沒(méi)有任何區(qū)別癞尚,就是在模板語(yǔ)法上有區(qū)別耸三。
SpringBoot與之整合
我們創(chuàng)建一個(gè)SpringBoot項(xiàng)目,添加相關(guān)依賴(lài)浇揩,下面我們就可以入門(mén)吧
pom.xml
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies>
自動(dòng)配置
自動(dòng)給我們默認(rèn)分配了模版的前綴和后綴仪壮,我們只需要按部就班的將模版丟進(jìn)去即可
我們寫(xiě)一個(gè)Controller:
將返回的對(duì)應(yīng)的模版添加到默認(rèn)的位置下:
編寫(xiě)配置文件application.yml:
然后編寫(xiě)一個(gè)springBoot的啟動(dòng)類(lèi),這里不多說(shuō)了胳徽,直接啟動(dòng)項(xiàng)目訪問(wèn)測(cè)試即可:
Thymeleaf常用語(yǔ)法
Thymeleaf的主要作用是把model中的數(shù)據(jù)渲染到html中积锅,因此其語(yǔ)法主要是如何解析model中的數(shù)據(jù)爽彤。從以下方面來(lái)學(xué)習(xí):
變量、方法缚陷、條件判斷适篙、循環(huán)、運(yùn)算 [ 邏輯運(yùn)算箫爷、布爾運(yùn)算嚷节、比較運(yùn)算、條件運(yùn)算 ]
其它
變量_變量案列
我們先新建一個(gè)實(shí)體類(lèi):User
publicclass User {
? ? String name;
? ? int age;
? ? User friend;// 對(duì)象類(lèi)型屬性}
然后在模型中添加數(shù)據(jù)
@GetMapping("test2")public String test2(Model model){
? ? User user =new User();
? ? user.setAge(21);
? ? user.setName("Jackson");
? ? user.setFriend(newUser("李小龍", 30));
?
? ? model.addAttribute("user", user);
? ? return"hello2";
}
語(yǔ)法說(shuō)明:
Thymeleaf通過(guò)${}來(lái)獲取model中的變量虎锚,注意這不是el表達(dá)式硫痰,而是ognl表達(dá)式,但是語(yǔ)法非常像翁都。
示例:
我們?cè)陧?yè)面獲取user數(shù)據(jù):
<h1>? ? 你好:<span th:text="${user.name}">請(qǐng)跟我來(lái)</span></h1>
感覺(jué)跟el表達(dá)式差不多的碍论。區(qū)別在于,我們的表達(dá)式寫(xiě)在一個(gè)名為:th:text的標(biāo)簽屬性中柄慰,這個(gè)叫做指令
變量_動(dòng)靜結(jié)合
指令:
Thymeleaf崇尚模板是純正的html代碼,脫離模板引擎税娜,在純靜態(tài)環(huán)境也可以直接運(yùn)行∽Γ現(xiàn)在如果我們直接在html中編寫(xiě)?${}這樣的表達(dá)式,顯然在靜態(tài)環(huán)境下就會(huì)出錯(cuò)敬矩,這不符合Thymeleaf的理念概行。
Thymeleaf中所有的表達(dá)式都需要寫(xiě)在"指令"中,指令是HTML5中的自定義屬性弧岳,在Thymeleaf中所有指令都是以th:開(kāi)頭凳忙。因?yàn)楸磉_(dá)式${user.name}是寫(xiě)在自定義屬性中,因此在靜態(tài)環(huán)境下禽炬,表達(dá)式的內(nèi)容會(huì)被當(dāng)做是普通字符串涧卵,瀏覽器會(huì)自動(dòng)忽略這些指令,這樣就不會(huì)報(bào)錯(cuò)了腹尖。
如果我們不經(jīng)過(guò)SpringMVC柳恐,而是直接用瀏覽器打開(kāi)編寫(xiě)的頁(yè)面:在靜態(tài)環(huán)境下,th指令不會(huì)被識(shí)別,但是也不會(huì)報(bào)錯(cuò)热幔,而是顯示標(biāo)簽的缺省默認(rèn)值:"請(qǐng)跟我來(lái)"
指令的設(shè)計(jì)乐设,正是Thymeleaf的高明之處,也是它優(yōu)于其它模板引擎的原因绎巨。動(dòng)靜結(jié)合的設(shè)計(jì)近尚,使得無(wú)論是前端開(kāi)發(fā)人員還是后端開(kāi)發(fā)人員可以完美契合。
向下兼容
但是要注意场勤,如果瀏覽器不支持Html5怎么辦戈锻?
如果不支持這種th:的命名空間寫(xiě)法介汹,那么可以把th:text換成?data-th-text,Thymeleaf也可以兼容舶沛。
escape
另外嘹承,th:text指令出于安全考慮,會(huì)把表達(dá)式讀取到的值進(jìn)行處理如庭,防止html的注入叹卷。
例如,<p>你好</p>將會(huì)被格式化輸出為$lt;p$gt;你好$lt;/p$lt;坪它。
如果想要不進(jìn)行格式化輸出骤竹,而是要輸出原始內(nèi)容,則使用th:utext來(lái)代替.
變量_ognl表達(dá)式的語(yǔ)法糖
剛才獲取變量值往毡,我們使用的是經(jīng)典的對(duì)象.屬性名方式蒙揣。但有些情況下,我們的屬性名可能本身也是變量开瞭,怎么辦懒震?
ognl提供了類(lèi)似js的語(yǔ)法方式:
例如:${user.name}?可以寫(xiě)作${user['name']}
變量_自定義變量
場(chǎng)景
看下面的案例:
<h2><p>Name:<span th:text="${user.name}">Jack</span>.</p><p>Age:<span th:text="${user.age}">21</span>.</p><p>friend:<span th:text="${user.friend.name}">Rose</span>.</p></h2>
我們獲取用戶(hù)的所有信息,分別展示嗤详。
當(dāng)數(shù)據(jù)量比較多的時(shí)候个扰,頻繁的寫(xiě)user.就會(huì)非常麻煩。
因此葱色,Thymeleaf提供了自定義變量來(lái)解決:
示例:
<h2 th:object="${user}"><p>Name:<span th:text="*{name}">Jack</span>.</p><p>Age:<span th:text="*{age}">21</span>.</p><p>friend:<span th:text="*{friend.name}">Rose</span>.</p></h2>
首先在?h2上 用?th:object="${user}"獲取user的值递宅,并且保存
然后,在h2內(nèi)部的任意元素上苍狰,可以通過(guò)?*{屬性名}的方式办龄,來(lái)獲取user中的屬性,這樣就省去了大量的user.前綴了
方法
ognl表達(dá)式中的方法調(diào)用
ognl表達(dá)式本身就支持方法調(diào)用淋昭,例如:
<h2 th:object="${user}"><p>FirstName:<span th:text="*{name.split(' ')[0]}">Jack</span>.</p><p>LastName:<span th:text="*{name.split(' ')[1]}">Li</span>.</p></h2>
這里我們調(diào)用了name(是一個(gè)字符串)的split方法俐填。
Thymeleaf內(nèi)置對(duì)象
Thymeleaf中提供了一些內(nèi)置對(duì)象,并且在這些對(duì)象中提供了一些方法响牛,方便我們來(lái)調(diào)用玷禽。獲取這些對(duì)象,需要使用#對(duì)象名來(lái)引用呀打。
一些環(huán)境相關(guān)對(duì)象
對(duì)象作用
#ctx獲取Thymeleaf自己的Context對(duì)象
#requset如果是web程序矢赁,可以獲取HttpServletRequest對(duì)象
#response如果是web程序,可以獲取HttpServletReponse對(duì)象
#session如果是web程序贬丛,可以獲取HttpSession對(duì)象
#servletContext如果是web程序撩银,可以獲取HttpServletContext對(duì)象
Thymeleaf提供的全局對(duì)象:
對(duì)象作用
#dates處理java.util.date的工具對(duì)象
#calendars處理java.util.calendar的工具對(duì)象
#numbers用來(lái)對(duì)數(shù)字格式化的方法
#strings用來(lái)處理字符串的方法
#bools用來(lái)判斷布爾值的方法
#arrays用來(lái)護(hù)理數(shù)組的方法
#lists用來(lái)處理List集合的方法
#sets用來(lái)處理set集合的方法
#maps用來(lái)處理map集合的方法
舉例
我們?cè)诃h(huán)境變量中添加日期類(lèi)型對(duì)象
@GetMapping("test3")public String show3(Model model){
? ? model.addAttribute("today",new Date());
? ? return"hello3";
}
在頁(yè)面中處理
<p>? 今天是: <span th:text="${#dates.format(today,'yyyy-MM-dd')}">2018-04-25</span></p>
方法_字面值
有的時(shí)候,我們需要在指令中填寫(xiě)基本類(lèi)型如:字符串豺憔、數(shù)值额获、布爾等够庙,并不希望被Thymeleaf解析為變量,這個(gè)時(shí)候稱(chēng)為字面值抄邀。
字符串字面值
使用一對(duì)'引用的內(nèi)容就是字符串字面值了:
<p>? 你正在觀看 <span th:text="'thymeleaf'">template</span> 的字符串常量值.</p>
th:text中的thymeleaf并不會(huì)被認(rèn)為是變量耘眨,而是一個(gè)字符串
數(shù)字字面值
數(shù)字不需要任何特殊語(yǔ)法, 寫(xiě)的什么就是什么境肾,而且可以直接進(jìn)行算術(shù)運(yùn)算
<p>今年是<span th:text="2018">1900</span>.</p><p>兩年后將會(huì)是<span th:text="2018 + 2">1902</span>.</p>
布爾字面值
布爾類(lèi)型的字面值是true或false:
<div th:if="true">? ? 你填的是true</div>
這里引用了一個(gè)th:if指令剔难,跟vue中的v-if類(lèi)似
方法_拼接
我們經(jīng)常會(huì)用到普通字符串與表達(dá)式拼接的情況:
<span th:text="'歡迎您:' + ${user.name} + '!'"></span>
字符串字面值需要用'',拼接起來(lái)非常麻煩奥喻,Thymeleaf對(duì)此進(jìn)行了簡(jiǎn)化偶宫,使用一對(duì)|即可:
<span th:text="|歡迎您:${user.name}|"></span>
運(yùn)算
需要注意:${}內(nèi)部的是通過(guò)OGNL表達(dá)式引擎解析的,外部的才是通過(guò)Thymeleaf的引擎解析环鲤,因此運(yùn)算符盡量放在${}外進(jìn)行纯趋。
算術(shù)運(yùn)算
支持的算術(shù)運(yùn)算符:+ - * / %
<span th:text="${user.age}"></span>? ? ? ? //21<span th:text="${user.age}%2 == 0"></span>//false
比較運(yùn)算
支持的比較運(yùn)算:>,?<,?>=?and?<=?,但是>,?<不能直接使用冷离,因?yàn)閤ml會(huì)解析為標(biāo)簽吵冒,要使用別名。
注意?==?and?!=不僅可以比較數(shù)值酒朵,類(lèi)似于equals的功能桦锄。
可以使用的別名:gt (>), lt (<), ge (>=), le (<=), not (!). Also eq (==), neq/ne (!=).
條件運(yùn)算
三元運(yùn)算
<span th:text="${user.sex} ? '男':'女'"></span>
默認(rèn)值
有的時(shí)候,我們?nèi)∫粋€(gè)值可能為空蔫耽,這個(gè)時(shí)候需要做非空判斷,可以使用?表達(dá)式 ?: 默認(rèn)值簡(jiǎn)寫(xiě):
<span th:text="${user.name} ?: '二狗'"></span>
當(dāng)前面的表達(dá)式值為null時(shí)留夜,就會(huì)使用后面的默認(rèn)值匙铡。
注意:?:之間沒(méi)有空格。
循環(huán)
循環(huán)也是非常頻繁使用的需求碍粥,我們使用th:each指令來(lái)完成:
假如有用戶(hù)的集合:users在Context中鳖眼。
<tr th:each="user : ${users}"><td th:text="${user.name}">Onions</td><td th:text="${user.age}">2.41</td></tr>
${users} 是要遍歷的集合,可以是以下類(lèi)型:
Iterable嚼摩,實(shí)現(xiàn)了Iterable接口的類(lèi)
Enumeration钦讳,枚舉
Interator,迭代器
Map枕面,遍歷得到的是Map.Entry
Array愿卒,數(shù)組及其它一切符合數(shù)組結(jié)果的對(duì)象
在迭代的同時(shí),我們也可以獲取迭代的狀態(tài)對(duì)象:
<tr th:each="user,stat : ${users}"><td th:text="${user.name}">Onions</td><td th:text="${user.age}">2.41</td></tr>
stat對(duì)象包含以下屬性:
index潮秘,從0開(kāi)始的角標(biāo)
count琼开,元素的個(gè)數(shù),從1開(kāi)始
size枕荞,總元素個(gè)數(shù)
current柜候,當(dāng)前遍歷到的元素
even/odd搞动,返回是否為奇偶,boolean值
first/last渣刷,返回是否為第一或最后鹦肿,boolean值
邏輯判斷
有了if和else,我們能實(shí)現(xiàn)一切功能^_^辅柴。
Thymeleaf中使用th:if?或者?th:unless?箩溃,兩者的意思恰好相反。
<span th:if="${user.age} > 24">老油條</span>
如果表達(dá)式的值為true碌识,則標(biāo)簽會(huì)渲染到頁(yè)面减牺,否則不進(jìn)行渲染。
以下情況被認(rèn)定為true:
表達(dá)式值為true
表達(dá)式值為非0數(shù)值
表達(dá)式值為非0字符
表達(dá)式值為字符串氨肌,但不是"false","no","off"
表達(dá)式不是布爾捂寿、字符串、數(shù)字魁瞪、字符中的任何一種
其它情況包括null都被認(rèn)定為false
分支控制switch
這里要使用兩個(gè)指令:th:switch?和?th:case
<div th:switch="${user.role}"><p th:case="'admin'">用戶(hù)是管理員</p><p th:case="'manager'">用戶(hù)是經(jīng)理</p><p th:case="*">用戶(hù)是別的玩意</p></div>
需要注意的是穆律,一旦有一個(gè)th:case成立,其它的則不再判斷导俘。與java中的switch是一樣的峦耘。
另外th:case="*"表示默認(rèn),放最后旅薄。
JS模板
模板引擎不僅可以渲染html辅髓,也可以對(duì)JS中的進(jìn)行預(yù)處理。而且為了在純靜態(tài)環(huán)境下可以運(yùn)行少梁,其Thymeleaf代碼可以被注釋起來(lái):
? ? const user =/*[[${user}]]*/ {};
? ? const age =/*[[${user.age}]]*/20;
? ? console.log(user);
? ? console.log(age)
在script標(biāo)簽中通過(guò)th:inline="javascript"來(lái)聲明這是要特殊處理的js腳本
語(yǔ)法結(jié)構(gòu):
const user = /*[[Thymeleaf表達(dá)式]]*/ "靜態(tài)環(huán)境下的默認(rèn)值";
因?yàn)門(mén)hymeleaf被注釋起來(lái)洛口,因此即便是靜態(tài)環(huán)境下, js代碼也不會(huì)報(bào)錯(cuò)凯沪,而是采用表達(dá)式后面跟著的默認(rèn)值第焰。且User對(duì)象會(huì)被直接處理為json格式。