Thymeleaf——入門與基本概述
一、概述
1.是什麼
簡單說, Thymeleaf 是一個跟 Velocity、FreeMarker 類似的模板引擎,它可以完全替代 JSP 。
2.feature
1.Thymeleaf 在有網路和無網路的環境下皆可執行,即它可以讓美工在瀏覽器檢視頁面的靜態效果,也可以讓程式設計師在伺服器檢視帶資料的動態頁面效果。這是由於它支援 html 原型,然後在 html 標籤裡增加額外的屬性來達到模板+資料的展示方式。瀏覽器解釋 html 時會忽略未定義的標籤屬性,所以 thymeleaf 的模板可以靜態地執行;當有資料返回到頁面時,Thymeleaf 標籤會動態地替換掉靜態內容,使頁面動態顯示。
2.Thymeleaf 開箱即用的特性。它提供標準和spring標準兩種方言,可以直接套用模板實現JSTL、 OGNL表示式效果,避免每天套模板、該jstl、改標籤的困擾。同時開發人員也可以擴充套件和建立自定義的方言。 3. Thymeleaf 提供spring標準方言和一個與 SpringMVC 完美整合的可選模組,可以快速的實現表單繫結、屬性編輯器、國際化等功能。
3.文件
官方教程:http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#what-is-thymeleaf
推薦教程:http://blog.didispace.com/springbootweb/
http://blog.csdn.net/u012706811/article/details/52185345
二、HelloWorld
1.引入依賴
springboot直接引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
非springboot專案使用如下依賴:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.4</version>
</dependency>
預設的模板對映路徑是:src/main/resources/templates,
springboot1.4之後,可以使用thymeleaf3來提高效率,並且解決標籤閉合問題,配置方式:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- set thymeleaf version -->
<thymeleaf.version>3.0.0.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version>
<!--set java version-->
<java.version>1.8</java.version>
</properties>
之前的model/modelMap/modelAndView等頁面資料傳遞參考之前隨筆:點選檢視
快速回顧:
package com.learndemo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value = "/return")
public class LearnReturnType {
/**
* Model本身不能設定頁面跳轉的url地址別名或者物理跳轉地址,那麼我們可以通過控制器方法的返回值來設定跳轉url
* 地址別名或者物理跳轉地址
*
* @param model
* 一個介面, 其實現類為ExtendedModelMap,繼承了ModelMap類
* @return 跳轉url地址別名或者物理跳轉地址
*/
@RequestMapping(value = "/index1")
public String index1(Model model) {
model.addAttribute("result", "後臺返回index1");
return "result";
}
/**
* ModelMap物件主要用於傳遞控制方法處理資料到結果頁面,類似於request物件的setAttribute方法的作用。 用法等同於Model
*
* @param model
* @return 跳轉url地址別名或者物理跳轉地址
*/
@RequestMapping(value = "/index2")
public String index2(ModelMap model) {
model.addAttribute("result", "後臺返回index2");
return "result";
}
/**
* ModelAndView主要有兩個作用 設定轉向地址和傳遞控制方法處理結果資料到結果頁面
* @return 返回一個模板檢視物件
*/
@RequestMapping(value = "/index3")
public ModelAndView index3() {
ModelAndView mv = new ModelAndView("result");
// ModelAndView mv = new ModelAndView();
// mv.setViewName("result");
mv.addObject("result", "後臺返回index3");
return mv;
}
/**
* map用來儲存遞控制方法處理結果資料,通過ModelAndView方法返回。
* 當然Model,ModelMap也可以通過這種方法返回
* @return 返回一個模板檢視物件
*/
@RequestMapping(value = "/index4")
public ModelAndView index4() {
Map<String, String> map = new HashMap<String, String>();
map.put("result", "後臺返回index4");
return new ModelAndView("result", map);
}
}
2.配置thymeleaf檢視解析器
這點與springMVC是相類似的:
#thymeleaf start
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
#開發時關閉快取,不然沒法看到實時頁面
spring.thymeleaf.cache=false
#thymeleaf end
實際專案中可能會有不太嚴格的HTML格式,此時設定mode=HTML5將會對非嚴格的報錯,可以參考以下配置:
spring.thymeleaf.mode=LEGACYHTML5
你可能會發現在預設配置下,thymeleaf對.html的內容要求很嚴格,比如<meta charset="UTF-8" />,
如果少最後的標籤封閉符號/,就會報錯而轉到錯誤頁。也比如你在使用Vue.js這樣的庫,然後有<div v-cloak></div>這樣的html程式碼,
也會被thymeleaf認為不符合要求而丟擲錯誤。
因此,建議增加下面這段:
spring.thymeleaf.mode = LEGACYHTML5
spring.thymeleaf.mode的預設值是HTML5,其實是一個很嚴格的檢查,改為LEGACYHTML5可以得到一個可能更友好親切的格式要求。
需要注意的是,LEGACYHTML5需要搭配一個額外的庫NekoHTML才可用。
- <dependency>
- <groupId>net.sourceforge.nekohtml</groupId>
- <artifactId>nekohtml</artifactId>
- <version>1.9.22</version>
- </dependency>
最後重啟專案就可以感受到不那麼嚴格的thymeleaf了。
這樣,需要的配置項如下:
# 一項是非嚴格的HTML檢查,一項是禁用快取來獲取實時頁面資料,其他採用預設項即可
thymeleaf:
mode: LEGACYHTML5
cache: false
//完整配置項參考類ThymeleafProperties
3。編寫控制器
/**
* 測試demo的controller
*
* @author zcc ON 2018/2/8
**/
@Controller
public class HelloController {
private static final Logger log = LoggerFactory.getLogger(HelloController.class);
@GetMapping(value = "/hello")
public String hello(Model model) {
String name = "jiangbei";
model.addAttribute("name", name);
return "hello";
}
}
4.編寫模板html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<!--/*@thymesVar id="name" type="java.lang.String"*/-->
<p th:text="'Hello!, ' + ${name} + '!'">3333</p>
</body>
</html>
其中,註釋是通過alt+enter進行自動生成的,便於IDEA補全,如果不加,IDEA將會報錯cannot reslove,
當然也可以通過如下方式解決,解決之前推薦在maven專案中reimport一下!(據說新版本的IDEA中已經修復此問題,待更新至2017.3以後)
5.測試
三、基礎語法
1.建立HTML
由上文也可以知道需要在html中新增:
<html xmlns:th="http://www.thymeleaf.org">
這樣,下文才能正確使用th:*形式的標籤!
2.獲取變數值${...}
通過${…}進行取值,這點和ONGL表示式語法一致!
<!--/*@thymesVar id="name" type="java.lang.String"*/-->
<p th:text="'Hello!, ' + ${name} + '!'">3333</p>
選擇變量表達式*{...}
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text={nationality}">Saturn</span>.</p>
</div>
等價於
<div>
<p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p>
</div>
至於p裡面的原有的值只是為了給前端開發時做展示用的.這樣的話很好的做到了前後端分離。
這也是Thymeleaf非常好的一個特性:在無網路的情況下也能執行,也就是完全可以前端先寫出頁面,模擬資料展現效果,後端人員再拿此模板修改即可!
3.連結表示式: @{…}
用來配合link src href使用的語法,類似的標籤有: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>
<a href="details.html" th:href="@{order/{orderId}/details(orderId=${o.id})}">Content路徑,預設訪問static下的order資料夾</a>
4.文字替換
<span th:text="'Welcome to our application, ' + ${user.name} + '!'">
或者下面的表達方式:(只能包含表示式變數,而不能有條件判斷等!)
<span th:text="|Welcome to our application, ${user.name}!|">
5.運算子
數學運算
- 二元操作:+, - , * , / , %
- 一元操作: - (負)
邏輯運算
- 一元 : and or
- 二元 : !,not
比較運算(為避免轉義尷尬,可以使用括號中的英文進行比較運算!)
- 比較:> , < , >= , <= ( gt , lt , ge , le )
- 等於:== , != ( eq , ne )
條件運算
- If-then: (if) ? (then)
- If-then-else: (if) ? (then) : (else)
- Default: (value) ?: (defaultvalue)
-
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
6.條件
if/unless
使用th:if和th:unless屬性進行條件判斷,th:unless於th:if恰好相反,只有表示式中的條件不成立,才會顯示其內容。
<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
switch
<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>
7.迴圈
通過th:each
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<!-- 不存在則忽略,顯示hello null!(可以通過預設值進行設定)-->
<p th:text="'Hello ' + (${name}?:'admin')">3333</p>
<table>
<tr>
<th>ID</th>
<th>NAME</th>
<th>AGE</th>
</tr>
<tr th:each="emp : ${empList}">
<td th:text="${emp.id}">1</td>
<td th:text="${emp.name}">海</td>
<td th:text="${emp.age}">18</td>
</tr>
</table>
</body>
</html>
後臺:
@GetMapping(value = "/hello")
public String hello(Model model) {
List<Emp> empList = new ArrayList<>();
empList.add(new Emp(1, "校長", 24));
empList.add(new Emp(2, "書記", 28));
empList.add(new Emp(3, "小海", 25));
model.addAttribute("empList", empList);
return "hello";
}
效果:
更多迴圈深入,iterStat等示例,參考:http://blog.csdn.net/sun_jy2011/article/details/40710429
8.內建物件Utilites
一般不推薦在前端進行這些處理,前端頁面以減少邏輯為宜
#dates :
utility methods for java.util.Date objects: formatting, component extraction, etc. #calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers :
utility methods for formatting numeric objects.
#strings :
utility methods for String objects: contains, startsWith, prepending/appending, etc. #objects : utility methods for objects in general.
#bools :
utility methods for boolean evaluation. #arrays : utility methods for arrays.
#lists :
utility methods for lists.
#sets :
utility methods for sets.
#maps :
utility methods for maps.
#aggregates :
utility methods for creating aggregates on arrays or collections.
#messages :
utility methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{...} syntax.
#ids :
utility methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
常用示例:
/*
* 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()}
/*
* 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)}
完整參考:點選檢視
四、常用標籤
//類似於th:object和th:field等進行表單引數繫結還是很有用的!使用與注意事項,參見:這裡
參考博文:https://www.cnblogs.com/hjwublog/p/5051732.html
本文轉載自{---江北}的部落格,原文地址:https://www.cnblogs.com/jiangbei/p/8462294.html