SpringBoot--實戰(zhàn)開發(fā)--整合Thymeleaf模版(十)

一、Thymeleaf模版簡介

官方文檔:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-a-expression-basic-objects
中文文檔:
https://www.e-learn.cn/thymeleaf/thymeleaf-instroduce

SpringBoot提供了大量的模版引擎镀脂,包括FreeMarker缴阎、Groovy掏缎、Thymeleaf稠歉、Velcoity和Mustache箱蝠,SpringBoot中推薦使用Thymeleaf作為模版引擎,因為Thymeleaf提供了完美的SpringMVC支持。
Thymeleaf是一個java類庫宦搬,它是一個xml/xthml/html5的模版引擎牙瓢,可以作為MVC的Web應(yīng)用的View層。

  1. 通過xmlns:th=”http://www.thymeleaf.org”命名空間间校,將頁面轉(zhuǎn)換為動態(tài)試圖矾克,需要進行動態(tài)處理的元素使用“th:”作為前綴。
  2. 通過th:text=”${person.name}”訪問model中的屬性憔足。
  3. 通過th:each=”person:${people}”來做循環(huán)迭代胁附。
  4. 通過th:if=”${not #lists.isEmpty(people)}”來判斷people是否為空。
    5 .通過th:src=”@{jquery-3.3.1.min.js}”來訪問Web中的靜態(tài)資源滓彰。
  5. 通過th:inline=”javascript”來添加script標(biāo)簽控妻,這樣在JavaScript代碼中即可訪問model中的屬性值。
  6. 通過“[[${}]]”格式來獲得實際值揭绑。
    在傳統(tǒng)的SpringMVC中弓候,若我們需要集成一個模版引擎的話,需要定義ViewResolver他匪。而Thymeleaf提供了一個SpringTemplateEngine的類菇存,用來驅(qū)動SpringMVC下使用Thymeleaf模版引擎。而在SpringBoot中對Thymeleaf進行了自動配置邦蜜,可以在application中以spring.thymeleaf開發(fā)來進行配置依鸥,不配置的情況下模版的默認(rèn)目錄是templates。
    在src/main/resource/static中放入需要引入的靜態(tài)資源:Bootstrap和jQuery悼沈。根據(jù)默認(rèn)的原則在src/main/resource/templates下創(chuàng)建index.html文件贱迟。

二、SpringBoot整合Thymeleaf

  1. Maven依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  1. 靜態(tài)資源
    SpringBoot默認(rèn)的幾個靜態(tài)頁面的目錄:
    /static井辆、/public关筒、/resources 、/META-INF/resources

  2. 配置Thymeleaf杯缺,在application.properties下配置

#thymelea模板配置
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.mode=HTML5

spring.thymeleaf.cache
是否開啟模板緩存蒸播,默認(rèn)true
spring.thymeleaf.check-template-location
是否檢查模板路徑是否存在,默認(rèn)true
spring.thymeleaf.content-type
指定Content-Type萍肆,默認(rèn)為: text/html
spring.thymeleaf.enabled
是否允許MVC使用Thymeleaf袍榆,默認(rèn)為: true
spring.thymeleaf.encoding
指定模板的編碼,默認(rèn)為: UTF-8
spring.thymeleaf.excluded-view-names
指定不使用模板的視圖名稱塘揣,多個以逗號分隔.
spring.thymeleaf.mode
**指定模板的模式包雀,具體查看StandardTemplateModeHandlers,默認(rèn)為: HTML5
spring.thymeleaf.mode = LEGACYHTML5
spring.thymeleaf.mode的默認(rèn)值是HTML5亲铡,其實是一個很嚴(yán)格的檢查才写,改為LEGACYHTML5可以得到一個可能更友好親切的格式要求葡兑。
**
spring.thymeleaf.prefix
指定模板的前綴,默認(rèn)為:classpath:/templates/
spring.thymeleaf.suffix
指定模板的后綴赞草,默認(rèn)為:.html
spring.thymeleaf.template-resolver-order
指定模板的解析順序讹堤,默認(rèn)為第一個.
spring.thymeleaf.view-names
指定使用模板的視圖名,多個以逗號分隔.

  1. 編寫Controller
@Controller
public class IndexController {
    @GetMapping("/index")
    public ModelAndView test(ModelAndView mv) {
        //視圖文件名
        mv.setViewName("index");
        mv.addObject("name","歡迎使用Thymeleaf!");
        return mv;
    }
}
  1. 編寫html
    在src/main/resources/templates目錄下創(chuàng)建:index.html
<!--引入命名空間-->
<html xmlns:th="http://www.thymeleaf.org">
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8" />
    <title>thymeleaf示例</title>
</head>
<body>
<h1>Hello thymeleaf</h1>
<h2 th:text="'名稱:'+${name}">默認(rèn)值</h2>
</body>
</html>

文本需要th:text屬性來設(shè)置厨疙。我們可以在文本元素中添加默認(rèn)值洲守,這樣當(dāng)Thymeleaf引擎處理失敗的時候頁面會顯示默認(rèn)值。${...}是變量表達(dá)式沾凄,將括號中的變量替換為其值梗醇。

三、基礎(chǔ)語法

th屬性:
常用th屬性解讀
html有的屬性撒蟀,Thymeleaf基本都有叙谨,而常用的屬性大概有七八個。其中th屬性執(zhí)行的優(yōu)先級從1~8牙肝,數(shù)字越低優(yōu)先級越高唉俗。
1)th:text :設(shè)置當(dāng)前元素的文本內(nèi)容,相同功能的還有th:utext配椭,兩者的區(qū)別在于前者不會轉(zhuǎn)義html標(biāo)簽虫溜,后者會。優(yōu)先級不高:order=7
2)th:value:設(shè)置當(dāng)前元素的value值股缸,類似修改指定屬性的還有th:src衡楞,th:href。優(yōu)先級不高:order=6
3)th:each:遍歷循環(huán)元素敦姻,和th:text或th:value一起使用瘾境。注意該屬性修飾的標(biāo)簽位置,詳細(xì)往后看镰惦。優(yōu)先級很高:order=2
4)th:if:條件判斷迷守,類似的還有th:unless,th:switch旺入,th:case兑凿。優(yōu)先級較高:order=3
5)th:insert:代碼塊引入,類似的還有th:replace茵瘾,th:include礼华,三者的區(qū)別較大,若使用不恰當(dāng)會破壞html結(jié)構(gòu)拗秘,常用于公共代碼塊提取的場景圣絮。優(yōu)先級最高:order=1
6)th:fragment:定義代碼塊,方便被th:insert引用雕旨。優(yōu)先級最低:order=8
7)th:object:聲明變量扮匠,一般和*{}一起配合使用捧请,達(dá)到偷懶的效果。優(yōu)先級一般:order=4
8)th:attr:修改任意屬性棒搜,實際開發(fā)中用的較少血久,因為有豐富的其他th屬性幫忙,類似的還有th:attrappend帮非,th:attrprepend。優(yōu)先級一般:order=5

  1. 變量表達(dá)式 {} 使用方法:直接使用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>
  1. 選擇變量表達(dá)式 {}
    使用方法:首先通過th:object 獲取對象末盔,然后使用th:xx = "
    {}"獲取對象屬性。
    這種簡寫風(fēng)格極為清爽座慰,推薦大家在實際項目中使用陨舱。 例如:
    <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>
  2. 鏈接表達(dá)式 @{}
    使用方法:通過鏈接表達(dá)式@{}直接拿到應(yīng)用路徑,然后拼接靜態(tài)資源路徑版仔。例如:
<script th:src="@{/webjars/jquery/jquery.js}"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css">
  1. 片段表達(dá)式 ~{}
    Thymeleaf 3.0 引入了一個新的片段表達(dá)式游盲。形如:~{commons::footer}。
    該特性十分有用(比如解決定義通用的header和footer的問題)
    base.html

片段表達(dá)式是Thymeleaf的特色之一蛮粮,細(xì)粒度可以達(dá)到標(biāo)簽級別益缎,這是JSP無法做到的。
片段表達(dá)式擁有三種語法:
~{ viewName } 表示引入完整頁面
~{ viewName ::selector} 表示在指定頁面尋找片段 其中selector可為片段名然想、jquery選擇器等
~{ ::selector} 表示在當(dāng)前頁尋找
使用方法:首先通過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>

在實際使用中变泄,我們往往使用更簡潔的表達(dá)令哟,去掉表達(dá)式外殼直接填寫片段名。例如:

<!-- your.html -->
<div th:replace="common/head::static"></div>

值得注意的是妨蛹,使用替換路徑th:replace 開頭請勿添加斜杠屏富,避免部署運行的時候出現(xiàn)路徑報錯。(因為默認(rèn)拼接的路徑為spring.thymeleaf.prefix = classpath:/templates/)
支持兩種語法結(jié)構(gòu)
推薦:~{templatename::fragmentname}
支持:~{templatename::#id}
templatename:模版名蛙卤,Thymeleaf會根據(jù)模版名解析完整路徑:/resources/templates/templatename.html狠半,要注意文件的路徑。
fragmentname:片段名表窘,Thymeleaf通過th:fragment聲明定義代碼塊典予,即:th:fragment="fragmentname"
id:HTML的id選擇器,使用時要在前面加上#號乐严,不支持class選擇器瘤袖。
代碼塊表達(dá)式的使用
代碼塊表達(dá)式需要配合th屬性(th:insert,th:replace昂验,th:include)一起使用捂敌。
th:insert:將代碼塊片段整個插入到使用了th:insert的HTML標(biāo)簽中艾扮,
th:replace:將代碼塊片段整個替換使用了th:replace的HTML標(biāo)簽中,
th:include:將代碼塊片段包含的內(nèi)容插入到使用了th:include的HTML標(biāo)簽中占婉,
用一個官方例子來區(qū)分三者的不同泡嘴,第三部分會通過實戰(zhàn)再次用到該知識。

<!--th:fragment定義代碼塊標(biāo)識-->
<footer th:fragment="copy">
&copy; 2011 The Good Thymes Virtual Grocery
</footer>

<!--三種不同的引入方式-->
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>

<!--th:insert是在div中插入代碼塊逆济,即多了一層div-->
<div>
    <footer>
    &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
</div>
<!--th:replace是將代碼塊代替當(dāng)前div岖赋,其html結(jié)構(gòu)和之前一致-->
<footer>
&copy; 2011 The Good Thymes Virtual Grocery
</footer>
<!--th:include是將代碼塊footer的內(nèi)容插入到div中荣茫,即少了一層footer-->
<div>
&copy; 2011 The Good Thymes Virtual Grocery
</div>
  1. 消息表達(dá)式
    即通常的國際化屬性:#{msg} 用于獲取國際化語言翻譯值。例如:
 <title th:text="#{user.title}"></title>
  1. 其它表達(dá)式
    在基礎(chǔ)語法中,默認(rèn)支持字符串連接钝的、數(shù)學(xué)運算涛舍、布爾邏輯和三目運算等王凑。例如:
<input name="name" th:value="${'I am '+(user.name!=null?user.name:'NoBody')}"/>
  1. 注釋
    Thymeleaf 注釋:
1获雕、<!--/* This code will be removed at Thymeleaf parsing time! */-->

2、<!--/*--> 
  <div>
     you can see me only before Thymeleaf processes me!
  </div>
<!--*/-->

3岛马、<!--/*/
  <div th:text="${...}">
    ...
  </div>
/*/-->

四棉姐、迭代循環(huán)

想要遍歷List集合很簡單,配合th:each 即可快速完成迭代啦逆。例如遍歷用戶列表:

<div th:each="user:${userList}">
    賬號:<input th:value="${user.username}"/>
    密碼:<input th:value="${user.password}"/>
</div>

在集合的迭代過程還可以獲取狀態(tài)變量伞矩,只需在變量后面指定狀態(tài)變量名即可,狀態(tài)變量可用于獲取集合的下標(biāo)/序號蹦浦、總數(shù)扭吁、是否為單數(shù)/偶數(shù)行、是否為第一個/最后一個盲镶。例如:

<div th:each="user,stat:${userList}" th:class="${stat.even}?'even':'odd'">
    下標(biāo):<input th:value="${stat.index}"/>
    序號:<input th:value="${stat.count}"/>
    賬號:<input th:value="${user.username}"/>
    密碼:<input th:value="${user.password}"/>
</div>

如果缺省狀態(tài)變量名侥袜,則迭代器會默認(rèn)幫我們生成以變量名開頭的狀態(tài)變量 xxStat, 例如:

<div th:each="user:${userList}" th:class="${userStat.even}?'even':'odd'">
    下標(biāo):<input th:value="${userStat.index}"/>
    序號:<input th:value="${userStat.count}"/>
    賬號:<input th:value="${user.username}"/>
    密碼:<input th:value="${user.password}"/>
</div>

th:remove
th:remove的值如下:
  1.all:刪除包含標(biāo)簽和所有的孩子溉贿。
  2.body:不包含標(biāo)記刪除,但刪除其所有的孩子枫吧。
  3.tag:包含標(biāo)記的刪除,但不刪除它的孩子。
  4.all-but-first:刪除所有包含標(biāo)簽的孩子,除了第一個宇色。
  5.none:什么也不做九杂。這個值是有用的動態(tài)評估。

五宣蠕、條件判斷

條件判斷通常用于動態(tài)頁面的初始化例隆,例如:

<div th:if="${userList}">
    <div>的確存在..</div>
</div>

如果想取反則使用unless 例如:

<div th:unless="${userList}">
    <div>不存在..</div>
</div>

六、日期格式化

使用默認(rèn)的日期格式(toString方法) 并不是我們預(yù)期的格式: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')}"/>

七抢蚀、內(nèi)聯(lián)寫法

(1)為什么要使用內(nèi)聯(lián)寫法镀层?·答:因為 JS無法獲取服務(wù)端返回的變量。
(2)如何使用內(nèi)聯(lián)表達(dá)式皿曲?答:標(biāo)準(zhǔn)格式為:[[${xx}]] 唱逢,可以讀取服務(wù)端變量吴侦,也可以調(diào)用內(nèi)置對象的方法。例如獲取用戶變量和應(yīng)用路徑:

    <script th:inline="javascript">
        var user = [[${user}]];`
        var APP_PATH = [[${#request.getContextPath()}]];
        var LANG_COUNTRY = [[${#locale.getLanguage()+'_'+#locale.getCountry()}]];
    </script>

(3)標(biāo)簽引入的JS里面能使用內(nèi)聯(lián)表達(dá)式嗎坞古?答:不能备韧!內(nèi)聯(lián)表達(dá)式僅在頁面生效,因為Thymeleaf只負(fù)責(zé)解析一級視圖痪枫,不能識別外部標(biāo)簽JS里面的表達(dá)式织堂。

八、七大基礎(chǔ)對象:

${#ctx} 上下文對象奶陈,可用于獲取其它內(nèi)置對象捧挺。
${#vars}:    上下文變量。
${#locale}:上下文區(qū)域設(shè)置尿瞭。
${#request}: HttpServletRequest對象。
${#response}: HttpServletResponse對象翅睛。
${#session}: HttpSession對象声搁。
${#servletContext}:  ServletContext對象。
常用的工具類:
#strings:字符串工具類
#lists:List 工具類
#arrays:數(shù)組工具類
#sets:Set 工具類
#maps:常用Map方法捕发。
#objects:一般對象類疏旨,通常用來判斷非空
#bools:常用的布爾方法。
#execInfo:獲取頁面模板的處理信息扎酷。
#messages:在變量表達(dá)式中獲取外部消息的方法檐涝,與使用#{...}語法獲取的方法相同。
#uris:轉(zhuǎn)義部分URL / URI的方法法挨。
#conversions:用于執(zhí)行已配置的轉(zhuǎn)換服務(wù)的方法谁榜。
#dates:時間操作和時間格式化等。
#calendars:用于更復(fù)雜時間的格式化凡纳。
#numbers:格式化數(shù)字對象的方法窃植。
#aggregates:在數(shù)組或集合上創(chuàng)建聚合的方法。
#ids:處理可能重復(fù)的id屬性的方法荐糜。

九巷怜、常見問題

  1. 去掉IDE thymeleaf Html顯示紅色波浪線
    打開IDE的file->setting->左上角搜索inspections,然后在右邊的搜索欄輸入thy,就會顯示如下頁面暴氏,將Expression variables validation的√去掉延塑,然后點擊確定。


    紅色波浪線
  2. 日期格式處理
    添加:
    @Column
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date createtime;

顯示:

//java代碼:
    @GetMapping("/index")
    public String test(Model model) {
        model.addAttribute("date",new Date());
        //視圖文件名
        return "index";
    }
//H5界面
<span th:text="${#dates.format(date, 'yyyy-MM-dd')}">2018-05-06</span>
    或者
<span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}">2019-05-06 00:00:00</span>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末答渔,一起剝皮案震驚了整個濱河市关带,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌研儒,老刑警劉巖豫缨,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件独令,死亡現(xiàn)場離奇詭異,居然都是意外死亡好芭,警方通過查閱死者的電腦和手機燃箭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舍败,“玉大人招狸,你說我怎么就攤上這事×谑恚” “怎么了裙戏?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長厕诡。 經(jīng)常有香客問我累榜,道長,這世上最難降的妖魔是什么灵嫌? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任壹罚,我火速辦了婚禮,結(jié)果婚禮上寿羞,老公的妹妹穿的比我還像新娘猖凛。我一直安慰自己,他們只是感情好绪穆,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布辨泳。 她就那樣靜靜地躺著,像睡著了一般玖院。 火紅的嫁衣襯著肌膚如雪菠红。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天难菌,我揣著相機與錄音途乃,去河邊找鬼。 笑死扔傅,一個胖子當(dāng)著我的面吹牛耍共,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猎塞,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼试读,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了荠耽?” 一聲冷哼從身側(cè)響起钩骇,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后倘屹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體银亲,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年纽匙,在試婚紗的時候發(fā)現(xiàn)自己被綠了务蝠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡烛缔,死狀恐怖馏段,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情践瓷,我是刑警寧澤院喜,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站晕翠,受9級特大地震影響喷舀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜淋肾,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一元咙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧巫员,春花似錦、人聲如沸甲棍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽感猛。三九已至七扰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陪白,已是汗流浹背颈走。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咱士,地道東北人立由。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像序厉,于是被迫代替她去往敵國和親锐膜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容