細(xì)品 Spring Boot+Thymeleaf,還有這么多好玩的細(xì)節(jié)!
文章目錄
1. Thymeleaf 簡(jiǎn)介
2.1 基本用法
2.2 手動(dòng)渲染
3. Thymeleaf 細(xì)節(jié)
3.1 標(biāo)準(zhǔn)表達(dá)式語(yǔ)法
3.1.1 簡(jiǎn)單表達(dá)式
3.1.2 字面量
3.1.3 文本運(yùn)算
3.1.4 算術(shù)運(yùn)算
3.1.5 布爾運(yùn)算
3.1.6 比較和相等
3.1.7 條件運(yùn)算符
3.1.8 內(nèi)置對(duì)象
3.2 設(shè)置屬性值
3.3 遍歷
3.4 分支語(yǔ)句
3.5 本地變量
3.6 內(nèi)聯(lián)
4. 小結(jié)
Thymeleaf 簡(jiǎn)潔漂亮、容易理解,并且完美支持 HTML5,可以直接打開(kāi)靜態(tài)頁(yè)面,同時(shí)不新增標(biāo)簽,只需增強(qiáng)屬性,這樣也降低了學(xué)習(xí)成本。
因此松哥今天花點(diǎn)時(shí)間和大家仔細(xì)分享一下 Thymeleaf。
1. Thymeleaf 簡(jiǎn)介
Thymeleaf 是新一代 Java 模板引擎,它類似于 Velocity、FreeMarker 等傳統(tǒng) Java 模板引擎,但是與傳統(tǒng) Java 模板引擎不同的是,Thymeleaf 支持 HTML 原型。
它既可以讓前端工程師在瀏覽器中直接打開(kāi)查看樣式,也可以讓后端工程師結(jié)合真實(shí)數(shù)據(jù)查看顯示效果,同時(shí),springboot 提供了 Thymeleaf 自動(dòng)化配置解決方案,因此在 SpringBoot 中使用 Thymeleaf 非常方便。
事實(shí)上, Thymeleaf 除了展示基本的 HTML ,進(jìn)行頁(yè)面渲染之外,也可以作為一個(gè) HTML 片段進(jìn)行渲染,例如我們?cè)谧鲟]件發(fā)送時(shí),可以使用 Thymeleaf 作為郵件發(fā)送模板。
另外,由于 Thymeleaf 模板后綴為 .html,可以直接被瀏覽器打開(kāi),因此,預(yù)覽時(shí)非常方便。
2. 整合 Spring Boot
2.1 基本用法
Spring Boot 中整合 Thymeleaf 非常容易,只需要?jiǎng)?chuàng)建項(xiàng)目時(shí)添加 Thymeleaf 即可:
創(chuàng)建完成后,pom.xml 依賴如下:
1
2
3
4
5
6
7
8
當(dāng)然,Thymeleaf 不僅僅能在 Spring Boot 中使用,也可以使用在其他地方,只不過(guò) Spring Boot 針對(duì) Thymeleaf 提供了一整套的自動(dòng)化配置方案,這一套配置類的屬性在 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties 中,部分源碼如下:
@ConfigurationProperties(prefix = "spring.thymeleaf") public class ThymeleafProperties { private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8; public static final String DEFAULT_PREFIX = "classpath:/templates/"; public static final String DEFAULT_SUFFIX = ".html"; private boolean checkTemplate = true; private boolean checkTemplateLocation = true; private String prefix = DEFAULT_PREFIX; private String suffix = DEFAULT_SUFFIX; private String mode = "HTML"; private Charset encoding = DEFAULT_ENCODING; private boolean cache = true; //... }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
首先通過(guò) @ConfigurationProperties 注解,將 application.properties 前綴為 spring.thymeleaf 的配置和這個(gè)類中的屬性綁定。
前三個(gè) static 變量定義了默認(rèn)的編碼格式、視圖解析器的前綴、后綴等。
從前三行配置中,可以看出來(lái),Thymeleaf 模板的默認(rèn)位置在 resources/templates 目錄下,默認(rèn)的后綴是 html 。
這些配置,如果開(kāi)發(fā)者不自己提供,則使用 默認(rèn)的,如果自己提供,則在 application.properties 中以 spring.thymeleaf 開(kāi)始相關(guān)的配置。
而我們剛剛提到的,Spring Boot 為 Thymeleaf 提供的自動(dòng)化配置類,則是 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration ,部分源碼如下:
@Configuration @EnableConfigurationProperties(ThymeleafProperties.class) @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class }) @AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class }) public class ThymeleafAutoConfiguration { }
1
2
3
4
5
6
可以看到,在這個(gè)自動(dòng)化配置類中,首先導(dǎo)入 ThymeleafProperties ,然后 @ConditionalOnClass 注解表示當(dāng)當(dāng)前系統(tǒng)中存在 TemplateMode 和 SpringTemplateEngine 類時(shí),當(dāng)前的自動(dòng)化配置類才會(huì)生效,即只要項(xiàng)目中引入了 Thymeleaf 相關(guān)的依賴,這個(gè)配置就會(huì)生效。
這些默認(rèn)的配置我們幾乎不需要做任何更改就可以直接使用了。如果開(kāi)發(fā)者有特殊需求,則可以在 application.properties 中配置以 spring.thymeleaf 開(kāi)頭的屬性即可。
接下來(lái)我們就可以創(chuàng)建 Controller 了,實(shí)際上引入 Thymeleaf 依賴之后,我們可以不做任何配置。新建的 IndexController 如下:
@Controller public class IndexController { @GetMapping("/index") public String index(Model model) { List
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
在 IndexController 中返回邏輯視圖名+數(shù)據(jù),邏輯視圖名為 index ,意思我們需要在 resources/templates 目錄下提供一個(gè)名為 index.html 的 Thymeleaf 模板文件。
創(chuàng)建 Thymeleaf
編號(hào) | 用戶名 | 地址 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
在 Thymeleaf 中,通過(guò) th:each 指令來(lái)遍歷一個(gè)集合,數(shù)據(jù)的展示通過(guò) th:text 指令來(lái)實(shí)現(xiàn),
注意 index.html 最上面引入 thymeleaf 名稱空間(最新版并無(wú)強(qiáng)制要求)。
配置完成后,就可以啟動(dòng)項(xiàng)目了,訪問(wèn) /index 接口,就能看到集合中的數(shù)據(jù)了:
2.2 手動(dòng)渲染
前面我們說(shuō)的是返回一個(gè) Thymeleaf 模板,我們也可以手動(dòng)渲染 Thymeleaf 模板,這個(gè)一般在郵件發(fā)送時(shí)候有用,例如我在 resources/templates 目錄下新建一個(gè)郵件模板,如下:
hello 歡迎 加入 XXX 集團(tuán),您的入職信息如下:
職位 | |
薪水 |

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
這一個(gè) HTML 模板中,有幾個(gè)變量,我們要將這個(gè) HTML 模板渲染成一個(gè) String 字符串,再把這個(gè)字符串通過(guò)郵件發(fā)送出去,那么如何手動(dòng)渲染呢?
@Autowired TemplateEngine templateEngine; @Test public void test1() throws MessagingException { Context context = new Context(); context.setVariable("username", "javaboy"); context.setVariable("position", "Java工程師"); context.setVariable("salary", 99999); String mail = templateEngine.process("mail", context); //省略郵件發(fā)送 }
1
2
3
4
5
6
7
8
9
10
11
渲染時(shí),我們需要首先注入一個(gè) TemplateEngine 對(duì)象,這個(gè)對(duì)象就是在 Thymeleaf 的自動(dòng)化配置類中配置的(即當(dāng)我們引入 Thymeleaf 的依賴之后,這個(gè)實(shí)例就有了)。
然后構(gòu)造一個(gè) Context 對(duì)象用來(lái)存放變量。
調(diào)用 process 方法進(jìn)行渲染,該方法的返回值就是渲染后的 HTML 字符串,然后我們將這個(gè)字符串發(fā)送出去。
3. Thymeleaf 細(xì)節(jié)
前面兩個(gè)案例讓小伙伴們大致上理解了在 Spring Boot 中要如何使用 Thymeleaf,接下來(lái),松哥將詳細(xì)介紹 Thymeleaf 本身的一些具體用法。
3.1 標(biāo)準(zhǔn)表達(dá)式語(yǔ)法
${...}
直接使用 th:xx = "${}" 獲取對(duì)象屬性。這個(gè)在前面的案例中已經(jīng)演示過(guò)了,不再贅述。
*{...}
可以像 ${...} 一樣使用,也可以通過(guò) th:object 獲取對(duì)象,然后使用 th:xx = "*{}" 獲取對(duì)象屬性,這種簡(jiǎn)寫(xiě)風(fēng)格極為清爽,推薦大家在實(shí)際項(xiàng)目中使用。
用戶名 | |
地址 |
1
2
3
4
5
6
7
8
9
10
#{...}
通常的國(guó)際化屬性:#{...} 用于獲取國(guó)際化語(yǔ)言翻譯值。
在 resources 目錄下新建兩個(gè)文件:messages.properties 和 messages_zh_CN.properties,內(nèi)容如下:
messages.properties:
message = javaboy
1
messages_zh_CN.properties:
message = 江南一點(diǎn)雨
1
然后在 thymeleaf 中引用 message,系統(tǒng)會(huì)根據(jù)瀏覽器的語(yǔ)言環(huán)境顯示不同的值:
1
@{...}
引用絕對(duì) URL:
1
等價(jià)于:
1
上下文相關(guān)的 URL:
首先在 application.properties 中配置 Spring Boot 的上下文,以便于測(cè)試:
server.servlet.context-path=/myapp
1
引用路徑:
1
等價(jià)于:
1
相對(duì) URL:
這個(gè)相對(duì)是指相對(duì)于服務(wù)器的 URL,例如如下引用:
1
等價(jià)于:
1
應(yīng)用程序的上下文 /myapp 將被忽略。
協(xié)議相對(duì) URL:
1
等價(jià)于:
1
帶參數(shù)的 URL:
1
等價(jià)于:
1
~{...}
片段表達(dá)式是 Thymeleaf 的特色之一,細(xì)粒度可以達(dá)到標(biāo)簽級(jí)別,這是 JSP 無(wú)法做到的。片段表達(dá)式擁有三種語(yǔ)法:
~{ viewName }:表示引入完整頁(yè)面
~{ viewName ::selector}:表示在指定頁(yè)面尋找片段,其中 selector 可為片段名、jquery選擇器等
~{ ::selector}: 表示在當(dāng)前頁(yè)尋找
舉個(gè)簡(jiǎn)單例子。
在 resources/templates 目錄下新建 my_fragment.html 文件,內(nèi)容如下:
1
2
這里有兩個(gè) div,通過(guò) th:fragment 來(lái)定義片段,兩個(gè) div 分別具有不同的名字。
然后在另外一個(gè)頁(yè)面中引用該片段:
用戶名 | |
地址 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
通過(guò) th:replace 來(lái)引用片段。第一個(gè)表示引用完整的 my_fragment.html 頁(yè)面;第二個(gè)表示引用 my_fragment.html 中的名為 javaboy_link 的片段;第三個(gè)表示引用當(dāng)前頁(yè)面名為 aaa 的片段,也就是上面那個(gè) table。
這些是一些可以直接寫(xiě)在表達(dá)式中的字符,主要有如下幾種:
文本字面量: ‘one text’, ‘Another one!’,…
數(shù)字字面量: 0, 34, 3.0, 12.3,…
布爾字面量: true, false
Null字面量: null
字面量標(biāo)記:one, sometext, main,…
案例:
1
2
3
4
如果文本是英文,并且不包含空格、逗號(hào)等字符,可以不用加單引號(hào)。
文本可以使用 + 進(jìn)行拼接。
1
2
如果字符串中包含變量,也可以使用另一種簡(jiǎn)單的方式,叫做字面量置換,用 | 代替 '...' + '...',如下:
1
2
算術(shù)運(yùn)算有:+, -, *, / 和 %。
1
2
3
th:with 定義了一個(gè)局部變量 age,在其所在的 div 中可以使用該局部變量。
二元運(yùn)算符:and, or
布爾非(一元運(yùn)算符):!, not
案例:
1
2
3
4
5
表達(dá)式里的值可以使用 >, <, >= 和 <= 符號(hào)比較。== 和 != 運(yùn)算符用于檢查相等(或者不相等)。注意 XML規(guī)定 < 和 > 標(biāo)簽不能用于屬性值,所以應(yīng)當(dāng)把它們轉(zhuǎn)義為 < 和 >。
如果不想轉(zhuǎn)義,也可以使用別名:gt (>);lt (<);ge (>=);le (<=);not (!)。還有 eq (==), neq/ne (!=)。
舉例:
1
2
3
4
5
6
7
8
類似于我們 Java 中的三目運(yùn)算符。
1
2
3
其中,: 后面的部分可以省略,如果省略了,又同時(shí)計(jì)算結(jié)果為 false 時(shí),將返回 null。
基本內(nèi)置對(duì)象:
#ctx:上下文對(duì)象。
#vars: 上下文變量。
#locale:上下文區(qū)域設(shè)置。
#request:(僅在 Web 上下文中)HttpServletRequest 對(duì)象。
#response:(僅在 Web 上下文中)HttpServletResponse 對(duì)象。
#session:(僅在 Web 上下文中)HttpSession 對(duì)象。
#servletContext:(僅在 Web 上下文中)ServletContext 對(duì)象。
在頁(yè)面可以訪問(wèn)到上面這些內(nèi)置對(duì)象,舉個(gè)簡(jiǎn)單例子:
1
實(shí)用內(nèi)置對(duì)象:
#execInfo:有關(guān)正在處理的模板的信息。
#messages:在變量表達(dá)式中獲取外部化消息的方法,與使用#{…}語(yǔ)法獲得的方式相同。
#uris:轉(zhuǎn)義URL / URI部分的方法
#conversions:執(zhí)行配置的轉(zhuǎn)換服務(wù)(如果有)的方法。
#dates:java.util.Date對(duì)象的方法:格式化,組件提取等
#calendars:類似于#dates但是java.util.Calendar對(duì)象。
#numbers:用于格式化數(shù)字對(duì)象的方法。
#strings:String對(duì)象的方法:contains,startsWith,prepending / appending等
#objects:一般對(duì)象的方法。
#bools:布爾評(píng)估的方法。
#arrays:數(shù)組方法。
#lists:列表的方法。
#sets:集合的方法。
#maps:地圖方法。
#aggregates:在數(shù)組或集合上創(chuàng)建聚合的方法。
#ids:處理可能重復(fù)的id屬性的方法(例如,作為迭代的結(jié)果)。
這是一些內(nèi)置對(duì)象以及工具方法,使用方式也都比較容易,如果使用的是 IntelliJ IDEA,都會(huì)自動(dòng)提示對(duì)象中的方法,很方便。
舉例:
1
2
3.2 設(shè)置屬性值
這個(gè)是給 HTML 元素設(shè)置屬性值。可以一次設(shè)置多個(gè),多個(gè)之間用 , 分隔開(kāi)。
例如:
1
會(huì)被渲染成:
1
當(dāng)然這種設(shè)置方法不太美觀,可讀性也不好。Thymeleaf 還支持在每一個(gè)原生的 HTML 屬性前加上 th: 前綴的方式來(lái)使用動(dòng)態(tài)值,像下面這樣:
1
這種寫(xiě)法看起來(lái)更清晰一些,渲染效果和前面一致。
上面案例中的 alt 和 title 則是兩個(gè)特殊的屬性,可以一次性設(shè)置,像下面這樣:
1
這個(gè)等價(jià)于前文的設(shè)置。
3.3 遍歷
數(shù)組/集合/Map/Enumeration/Iterator 等的遍歷也算是一個(gè)非常常見(jiàn)的需求,Thymeleaf 中通過(guò) th:each 來(lái)實(shí)現(xiàn)遍歷,像下面這樣:
1
2
3
4
5
6
users 是要遍歷的集合/數(shù)組,u 則是集合中的單個(gè)元素。
遍歷的時(shí)候,我們可能需要獲取遍歷的狀態(tài),Thymeleaf 也對(duì)此提供了支持:
index:當(dāng)前的遍歷索引,從0開(kāi)始。
count:當(dāng)前的遍歷索引,從1開(kāi)始。
size:被遍歷變量里的元素?cái)?shù)量。
current:每次遍歷的遍歷變量。
even/odd:當(dāng)前的遍歷是偶數(shù)次還是奇數(shù)次。
first:當(dāng)前是否為首次遍歷。
last:當(dāng)前是否為最后一次遍歷。
u 后面的 state 表示遍歷狀態(tài),通過(guò)遍歷狀態(tài)可以引用上面的屬性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
3.4 分支語(yǔ)句
只顯示奇數(shù)次的遍歷,可以使用 th:if,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
th:if 不僅僅只接受布爾值,也接受其他類型的值,例如如下值都會(huì)判定為 true:
如果值是布爾值,并且為 true。
如果值是數(shù)字,并且不為 0。
如果值是字符,并且不為 0。
如果值是字符串,并且不為 “false”, “off” 或者 “no”。
如果值不是布爾值,數(shù)字,字符或者字符串。
但是如果值為 null,th:if 會(huì)求值為 false。
th:unless 的判定條件則與 th:if 完全相反。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
這個(gè)顯示效果則與上面的完全相反。
當(dāng)可能性比較多的時(shí)候,也可以使用 switch:
odd even |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
th:case="*" 則表示默認(rèn)選項(xiàng)。
3.5 本地變量
這個(gè)我們前面已經(jīng)涉及到了,使用 th:with 可以定義一個(gè)本地變量。
3.6 內(nèi)聯(lián)
我們可以使用屬性將數(shù)據(jù)放入頁(yè)面模版中,但是很多時(shí)候,內(nèi)聯(lián)的方式看起來(lái)更加直觀一些,像下面這樣:
1
用內(nèi)聯(lián)的方式去做拼接也顯得更加自然。
[[...]] 對(duì)應(yīng)于 th:text (結(jié)果會(huì)是轉(zhuǎn)義的 HTML),[(...)]對(duì)應(yīng)于 th:utext,它不會(huì)執(zhí)行任何的 HTML 轉(zhuǎn)義。
像下面這樣:
1
2
3
4
最終的顯示效果如下:
不過(guò)內(nèi)聯(lián)方式有一個(gè)問(wèn)題。我們使用 Thymeleaf 的一大優(yōu)勢(shì)在于不用動(dòng)態(tài)渲染就可以直接在瀏覽器中看到顯示效果,當(dāng)我們使用屬性配置的時(shí)候確實(shí)是這樣,但是如果我們使用內(nèi)聯(lián)的方式,各種表達(dá)式就會(huì)直接展示在靜態(tài)網(wǎng)頁(yè)中。
也可以在 js 或者 css 中使用內(nèi)聯(lián),以 js 為例,使用方式如下:
1
2
3
4
js 中需要通過(guò) th:inline="javascript" 開(kāi)啟內(nèi)聯(lián)。
4. 小結(jié)
好啦,Thymeleaf 跟大家也介紹的差不多了,應(yīng)付日常的工作應(yīng)該是可以了。對(duì) Thymeleaf 感興趣的小伙伴,也可以看看它的官方文檔: https://www.thymeleaf.org。
最后,松哥還搜集了 50+ 個(gè)項(xiàng)目需求文檔,想做個(gè)項(xiàng)目練練手的小伙伴不妨看看哦~
需求文檔地址:https://gitee.com/lenve/javadoc
Spring Spring Boot
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。