SpringBoot Thymeleaf使用教程(實(shí)用版)

使用Thymeleaf 三大理由:

    1. 簡(jiǎn)潔漂亮 容易理解
    1. 完美支持HTML5 使用瀏覽器直接打開(kāi)頁(yè)面
    1. 不新增標(biāo)簽 只需增強(qiáng)屬性

學(xué)習(xí)目標(biāo)

  • 快速掌握Thymeleaf的基本使用(五大基礎(chǔ)語(yǔ)法+常用內(nèi)置對(duì)象)

快速查閱

專題閱讀:《SpringBoot 布道系列》

源碼下載:springboot-web-thymeleaf-enhance

— Hey Man衷畦,Don't forget to Star or Fork . —

官方指南: Thymleaf 3.0 官方教程

相關(guān)教程:SpringBoot Thymeleaf 基本介紹SpringBoot 在IDEA中實(shí)現(xiàn)熱部署(實(shí)用版)

使用教程

溫馨提示:Thymeleaf 最為顯著的特征是增強(qiáng)屬性驾霜,任何屬性都可以通過(guò)th:xx 來(lái)完成交互乎串,例如th:value最終會(huì)覆蓋value屬性店枣。

一、基礎(chǔ)語(yǔ)法

變量表達(dá)式 ${}

使用方法:直接使用th:xx = "${}" 獲取對(duì)象屬性 。例如:

<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>

選擇變量表達(dá)式 *{}

使用方法:首先通過(guò)th:object 獲取對(duì)象鸯两,然后使用th:xx = "*{}"獲取對(duì)象屬性闷旧。

這種簡(jiǎn)寫(xiě)風(fēng)格極為清爽,推薦大家在實(shí)際項(xià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>

鏈接表達(dá)式 @{}

使用方法:通過(guò)鏈接表達(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">

片段表達(dá)式 ~{}

片段表達(dá)式是Thymeleaf的特色之一钝侠,細(xì)粒度可以達(dá)到標(biāo)簽級(jí)別该园,這是JSP無(wú)法做到的。
片段表達(dá)式擁有三種語(yǔ)法:

  • ~{ viewName } 表示引入完整頁(yè)面
  • ~{ viewName ::selector} 表示在指定頁(yè)面尋找片段 其中selector可為片段名帅韧、jquery選擇器等
  • ~{ ::selector} 表示在當(dāng)前頁(yè)尋找

使用方法:首先通過(guò)th:fragment定制片段 里初,然后通過(guò)th:replace 填寫(xiě)片段路徑和片段名。例如:

<!-- /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>

在實(shí)際使用中忽舟,我們往往使用更簡(jiǎn)潔的表達(dá)双妨,去掉表達(dá)式外殼直接填寫(xiě)片段名。例如:

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

值得注意的是叮阅,使用替換路徑th:replace 開(kāi)頭請(qǐng)勿添加斜杠斥难,避免部署運(yùn)行的時(shí)候出現(xiàn)路徑報(bào)錯(cuò)。(因?yàn)槟J(rèn)拼接的路徑為spring.thymeleaf.prefix = classpath:/templates/

消息表達(dá)式

即通常的國(guó)際化屬性:#{msg} 用于獲取國(guó)際化語(yǔ)言翻譯值帘饶。例如:

 <title th:text="#{user.title}"></title>

其它表達(dá)式

在基礎(chǔ)語(yǔ)法中哑诊,默認(rèn)支持字符串連接、數(shù)學(xué)運(yùn)算及刻、布爾邏輯和三目運(yùn)算等镀裤。例如:

<input name="name" th:value="${'I am '+(user.name!=null?user.name:'NoBody')}"/>

二、內(nèi)置對(duì)象

官方文檔: 附錄A: Thymeleaf 3.0 基礎(chǔ)對(duì)象
官方文檔: 附錄B: Thymeleaf 3.0 工具類

七大基礎(chǔ)對(duì)象:

  • ${#ctx} 上下文對(duì)象缴饭,可用于獲取其它內(nèi)置對(duì)象暑劝。
  • ${#vars}: 上下文變量。
  • ${#locale}:上下文區(qū)域設(shè)置颗搂。
  • ${#request}: HttpServletRequest對(duì)象担猛。
  • ${#response}: HttpServletResponse對(duì)象。
  • ${#session}: HttpSession對(duì)象丢氢。
  • ${#servletContext}: ServletContext對(duì)象傅联。

常用的工具類:

  • #strings:字符串工具類
  • #lists:List 工具類
  • #arrays:數(shù)組工具類
  • #sets:Set 工具類
  • #maps:常用Map方法。
  • #objects:一般對(duì)象類疚察,通常用來(lái)判斷非空
  • #bools:常用的布爾方法蒸走。
  • #execInfo:獲取頁(yè)面模板的處理信息。
  • #messages:在變量表達(dá)式中獲取外部消息的方法貌嫡,與使用#{...}語(yǔ)法獲取的方法相同比驻。
  • #uris:轉(zhuǎn)義部分URL / URI的方法该溯。
  • #conversions:用于執(zhí)行已配置的轉(zhuǎn)換服務(wù)的方法。
  • #dates:時(shí)間操作和時(shí)間格式化等别惦。
  • #calendars:用于更復(fù)雜時(shí)間的格式化狈茉。
  • #numbers:格式化數(shù)字對(duì)象的方法。
  • #aggregates:在數(shù)組或集合上創(chuàng)建聚合的方法掸掸。
  • #ids:處理可能重復(fù)的id屬性的方法氯庆。

三、迭代循環(huán)

想要遍歷List集合很簡(jiǎn)單猾漫,配合th:each 即可快速完成迭代。例如遍歷用戶列表:

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

在集合的迭代過(guò)程還可以獲取狀態(tài)變量感凤,只需在變量后面指定狀態(tài)變量名即可悯周,狀態(tài)變量可用于獲取集合的下標(biāo)/序號(hào)、總數(shù)陪竿、是否為單數(shù)/偶數(shù)行禽翼、是否為第一個(gè)/最后一個(gè)。例如:

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

如果缺省狀態(tài)變量名族跛,則迭代器會(huì)默認(rèn)幫我們生成以變量名開(kāi)頭的狀態(tài)變量 xxStat闰挡, 例如:

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

四、條件判斷

條件判斷通常用于動(dòng)態(tài)頁(yè)面的初始化礁哄,例如:

<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}"/>

此時(shí)可以通過(guò)時(shí)間工具類#dates來(lái)對(duì)日期進(jìn)行格式化: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)寫(xiě)法

  • (1)為什么要使用內(nèi)聯(lián)寫(xiě)法桐绒?·答:因?yàn)?JS無(wú)法獲取服務(wù)端返回的變量夺脾。

  • (2)如何使用內(nèi)聯(lián)表達(dá)式?答:標(biāo)準(zhǔn)格式為:[[${xx}]] 茉继,可以讀取服務(wù)端變量咧叭,也可以調(diào)用內(nèi)置對(duì)象的方法。例如獲取用戶變量和應(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á)式僅在頁(yè)面生效,因?yàn)?code>Thymeleaf只負(fù)責(zé)解析一級(jí)視圖派撕,不能識(shí)別外部標(biāo)簽JS里面的表達(dá)式婉弹。

七、國(guó)際化

需要了解更多關(guān)于國(guó)際化的精彩描述請(qǐng)前往 SpringBoot 快速實(shí)現(xiàn)國(guó)際化i18n 终吼。

例如在國(guó)際化文件中編寫(xiě)了user.title這個(gè)鍵值马胧,然后使用#{}讀取這個(gè)KEY即可獲取翻譯。

    <title th:text="#{user.title}">用戶登陸</title>

八衔峰、詳細(xì)教程

======== 有了上述基礎(chǔ)后 下面正式開(kāi)始Thymeleaf 的詳細(xì)教程 ==============

首先通過(guò)Spring Initializr創(chuàng)建項(xiàng)目佩脊,如圖所示:

然后在POM文件引入web 蛙粘、thymeleaf等依賴:

<dependencies>
        <dependency><!--Web相關(guān)依賴-->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency><!--頁(yè)面模板依賴-->
            <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 配置頁(yè)面路徑:

spring:
  thymeleaf:
    cache: false #關(guān)閉緩存
    prefix: classpath:/views/ #調(diào)整頁(yè)面路徑

接著在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;
    //請(qǐng)讀者自行補(bǔ)充 構(gòu)造器和 get/set方法..
}

開(kāi)始編寫(xiě)公共頁(yè)面:src/main/resources/views/common/head.html ,其中static為頁(yè)面片段:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!--聲明static為頁(yè)面片段名稱-->
<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>

接著編寫(xiě)用戶列表頁(yè):src/main/resources/views/user/user.html 配合th:each顯示用戶列表信息威彰。

使用說(shuō)明:這里 th:replace="common/head::static" 表示將引用${spring.thymeleaf.prefix}/common/head.htmlstatic頁(yè)面片段出牧,值得注意的是由于替換路徑默認(rèn)會(huì)拼接前綴路徑,所以開(kāi)頭切勿在添加斜杠歇盼,否則在打包成JAR部署運(yùn)行時(shí)將提示報(bào)Templates not found... 舔痕。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title th:text="用戶信息">User</title>
    <!--默認(rèn)拼接前綴路徑,開(kāi)頭請(qǐng)勿再添加斜杠,防止部署運(yùn)行報(bào)錯(cuò)!-->
    <script th:replace="common/head::static"></script>
</head>
<body>

<div th:each="user,userStat:${userList}" th:class="${userStat.even}?'even':'odd'">
    序號(hào):<input type="text" th:value="${userStat.count}"/>
    賬號(hào):<input type="text" th:value="${user.username}"/>
    密碼:<input type="password" th:value="${user.password}"/>
    時(shí)間:<input type="text" th:value="${user.createTime}"/>
    時(shí)間:<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"/>
</div>

<script th:inline="javascript">
    //通過(guò)內(nèi)聯(lián)表達(dá)式獲取用戶信息
    var userList = [[${userList}]];
    console.log(userList)
</script>
</body>
</html>

然后編寫(xiě)單個(gè)用戶頁(yè)面:

至此大功告成豹缀,然后快速啟動(dòng)項(xiàng)目伯复,如圖所示:

快速啟動(dòng)項(xiàng)目

然后訪問(wèn)用戶列表: http://localhost:8080 ,如圖所示:

然后訪問(wèn)單個(gè)用戶: http://localhost:8080/user/1 邢笙,如圖所示:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末啸如,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子氮惯,更是在濱河造成了極大的恐慌叮雳,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妇汗,死亡現(xiàn)場(chǎng)離奇詭異帘不,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)杨箭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)寞焙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人互婿,你說(shuō)我怎么就攤上這事棺弊。” “怎么了擒悬?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵模她,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我懂牧,道長(zhǎng)侈净,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任僧凤,我火速辦了婚禮畜侦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘躯保。我一直安慰自己旋膳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布途事。 她就那樣靜靜地躺著验懊,像睡著了一般擅羞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上义图,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天减俏,我揣著相機(jī)與錄音,去河邊找鬼碱工。 笑死娃承,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怕篷。 我是一名探鬼主播历筝,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼廊谓!你這毒婦竟也來(lái)了梳猪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蹂析,失蹤者是張志新(化名)和其女友劉穎舔示,沒(méi)想到半個(gè)月后碟婆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體电抚,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年竖共,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蝙叛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡公给,死狀恐怖借帘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淌铐,我是刑警寧澤肺然,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站腿准,受9級(jí)特大地震影響际起,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吐葱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一街望、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弟跑,春花似錦灾前、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蔫敲。三九已至,卻和暖如春烧给,著一層夾襖步出監(jiān)牢的瞬間燕偶,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工础嫡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留指么,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓榴鼎,卻偏偏與公主長(zhǎng)得像伯诬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巫财,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353