SpringBoot入门:新一代Java模板引擎Thymeleaf(理论)
Spring Boot 提供了spring-boot-starter-web來為Web開發(fā)予以支持,spring-boot-starter-web為我們提供了嵌入的Tomcat以及SpringMVC的依賴,用起來很方便。
另外,我們這里還要用到模板引擎,Spring Boot提供了大量的模板引擎,包括FreeMarker、Groovy、Thymeleaf、Velocity和Mustache,在 提供的這么多中它推薦使用Thymeleaf。
Thymeleaf是一款用于渲染XML/XHTML/HTML5內(nèi)容的模板引擎。類似JSP,Velocity,FreeMaker等,它也可以輕易的與Spring MVC等Web框架進行集成作為Web應用的模板引擎。
與其它模板引擎相比,Thymeleaf最大的特點是能夠直接在瀏覽器中打開并正確顯示模板頁面,而不需要啟動整個Web應用。
Thymeleaf初探
相比于其他的模板引擎,Thymeleaf最大的特點是通過HTML的標簽屬性渲染標簽內(nèi)容,以下是一個Thymeleaf模板例子:
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all"
href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
</head>
<body>
<p th:text="#{home.welcome}">Welcome to our grocery store!</p>
</body>
</html>
這是一段標準的HTML代碼,這也就意味著通過瀏覽器直接打開它是可以正確解析它的結(jié)構(gòu)并看到頁面的樣子。相比去其他的模板引擎在指定的位置通過${}等表達式進行渲染,Thymeleaf則是一種針對HTML/XML定制的模板語言(當然它可以被擴展),它通過標簽中的th:text屬性來填充該標簽的一段內(nèi)容。上例中,<p th:text="#{home.welcome}">Welcome to our grocery store!</p>意味著<p>標簽中的內(nèi)容會被表達式#{home.welcome}的值所替代,無論模板中它的內(nèi)容是什么,之所以在模板中“多此一舉“地填充它的內(nèi)容,完全是為了它能夠作為原型在瀏覽器中直接顯示出來。
標準表達式語法
變量
Thymeleaf模板引擎在進行模板渲染時,還會附帶一個Context存放進行模板渲染的變量,在模板中定義的表達式本質(zhì)上就是從Context中獲取對應的變量的值:
<p>Today is: <span th:text="${today}">13 february 2011</span>.</p>
假設today的值為2015年8月14日,那么渲染結(jié)果為:<p>Today is: 2015年8月14日.</p>。可見Thymeleaf的基本變量和JSP一樣,都使用${.}表示獲取變量的值。
URL
URL在Web應用模板中占據(jù)著十分重要的地位,需要特別注意的是Thymeleaf對于URL的處理是通過語法@{...}來處理的。Thymeleaf支持絕對路徑URL:
<a th:href="@{http://www.thymeleaf.org}">Thymeleaf</a>
同時也能夠支持相對路徑URL:
當前頁面相對路徑URL——user/login.html,通常不推薦這樣寫。
Context相關URL——/static/css/style.css
另外,如果需要Thymeleaf對URL進行渲染,那么務必使用th:href,th:src等屬性,下面是一個例子
<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html"
th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a>
<!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>
<!-- Will produce '/gtvg/order/3/details' (plus rewriting) -->
<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
幾點說明:
上例中URL最后的(orderId=${o.id})表示將括號內(nèi)的內(nèi)容作為URL參數(shù)處理,該語法避免使用字符串拼接,大大提高了可讀性
@{...}表達式中可以通過{orderId}訪問Context中的orderId變量
@{/order}是Context相關的相對路徑,在渲染時會自動添加上當前Web應用的Context名字,假設context名字為app,那么結(jié)果應該是/app/order
字符串替換
很多時候可能我們只需要對一大段文字中的某一處地方進行替換,可以通過字符串拼接操作完成:
<span th:text="'Welcome to our application, ' + ${user.name} + '!'">
一種更簡潔的方式是:
<span th:text="|Welcome to our application, ${user.name}!|">
當然這種形式限制比較多,|...|中只能包含變量表達式${...},不能包含其他常量、條件表達式等。
運算符
在表達式中可以使用各類算術運算符,例如+, -, *, /, %
th:with="isEven=(${prodStat.count} % 2 == 0)"
邏輯運算符>, <, <=,>=,==,!=都可以使用,唯一需要注意的是使用<,>時需要用它的HTML轉(zhuǎn)義符:
th:if="${prodStat.count} > 1"
th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
循環(huán)
渲染列表數(shù)據(jù)是一種非常常見的場景,例如現(xiàn)在有n條記錄需要渲染成一個表格<table>,該數(shù)據(jù)集合必須是可以遍歷的,使用th:each標簽:
<body>
<h1>Product list</h1>
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
</tr>
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
</table>
<p>
<a href="../home.html" th:href="@{/}">Return to home</a>
</p>
</body>
可以看到,需要在被循環(huán)渲染的元素(這里是<tr>)中加入th:each標簽,其中th:each="prod : ${prods}"意味著對集合變量prods進行遍歷,循環(huán)變量是prod在循環(huán)體中可以通過表達式訪問。
條件求值
If/Unless
Thymeleaf中使用th:if和th:unless屬性進行條件判斷,下面的例子中,<a>標簽只有在th:if中條件成立時才顯示:
<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
th:unless于th:if恰好相反,只有表達式中的條件不成立,才會顯示其內(nèi)容。
Switch
Thymeleaf同樣支持多路選擇Switch結(jié)構(gòu):
<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
</div>
默認屬性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>
Utilities
為了模板更加易用,Thymeleaf還提供了一系列Utility對象(內(nèi)置于Context中),可以通過#直接訪問:
#dates
#calendars
#numbers
#strings
arrays
lists
sets
maps
...
下面用一段代碼來舉例一些常用的方法:
#dates
/*
* Format date with the specified pattern
* Also works with arrays, lists or sets
*/
${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
${#dates.arrayFormat(datesArray, 'dd/MMM/yyyy HH:mm')}
${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}
${#dates.setFormat(datesSet, 'dd/MMM/yyyy HH:mm')}
/*
* Create a date (java.util.Date) object for the current date and time
*/
${#dates.createNow()}
/*
* Create a date (java.util.Date) object for the current date (time set to 00:00)
*/
${#dates.createToday()}
#strings
/*
* Check whether a String is empty (or null). Performs a trim() operation before check
* Also works with arrays, lists or sets
*/
${#strings.isEmpty(name)}
${#strings.arrayIsEmpty(nameArr)}
${#strings.listIsEmpty(nameList)}
${#strings.setIsEmpty(nameSet)}
/*
* Check whether a String starts or ends with a fragment
* Also works with arrays, lists or sets
*/
${#strings.startsWith(name,'Don')} // also array*, list* and set*
${#strings.endsWith(name,endingFragment)} // also array*, list* and set*
/*
* Compute length
* Also works with arrays, lists or sets
*/
${#strings.length(str)}
/*
* Null-safe comparison and concatenation
*/
${#strings.equals(str)}
${#strings.equalsIgnoreCase(str)}
${#strings.concat(str)}
${#strings.concatReplaceNulls(str)}
/*
* Random
*/
${#strings.randomAlphanumeric(count)}
總結(jié)
以上是生活随笔為你收集整理的SpringBoot入门:新一代Java模板引擎Thymeleaf(理论)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MapReduce简介
- 下一篇: HYSBZ 1588 营业额统计 平衡二