在Java中,模板引擎可以幫助生成文本輸出。常見的模板引擎包括FreeMarker、Velocity和Thymeleaf等
Thymeleaf是一個適用于Web和獨立環境的現代服務器端Java模板引擎。
Thymeleaf 和 JSP比較:
Thymeleaf目前所作的工作和JSP有相似之處,Thymeleaf和JSP都是屬于服務端渲染技術,Thymeleaf比JSP功能強大許多。
Thymeleaf就是SpringBoot 官方推薦使用的模板引擎。
搭建thymeleaf環境:
1、創建一個 SpringBoot 項目
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.14</version><scope>provided</scope>
</dependency>
2、編寫跳轉頁面的 Controller
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private Integer id;private String name;private Integer age;private Date birthday;
}@Controller
public class IndexController {@RequestMapping("/index")public String index(Model model) {model.addAttribute("message", "HelloWorld");Student student = new Student(1, "李四", 23, new Date());model.addAttribute("student", student);Student student1 = new Student(1, "張三1", 23, new Date());Student student2 = new Student(2, "張三2", 23, new Date());Student student3 = new Student(3, "張三3", 23, new Date());List<Student> list = new ArrayList<>();list.add(student1);list.add(student2);list.add(student3);model.addAttribute("list", list);return "index";}
}
3、index.html 頁面
在resources/templates目錄創建一個index.html頁面。
注意,必須加上命名空間xmlns:th="Thymeleaf",否則Thymeleaf的自定義標簽沒有提示。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><!--使用th:text輸出--><div th:text="${message}"></div><input type="text" th:id="${student.id}" th:name="${student.name}" th:value="${student.name}"/><!--循環--><table border="1"><tr><td>編號</td><td>姓名</td><td>年齡</td><td>生日</td></tr><tr th:each="student:${list}"><td th:text="${student.id}">1</td><td th:text="${student.name}">張三</td><td th:text="${student.age}">23</td><td th:text="${#dates.format(student.birthday, 'yyyy-MM-dd')}">1990-12-13</td></tr></table><!--取出集合中某一個--><div th:text="${list[0].name}"></div>
</body>
</html>
疑難問題
問題:為什么thymeleaf頁面放在templates文件夾里面,并且后綴要是.html呢?
SpringBoot框架會將內置支持的功能組件放在spring-boot-autoconfigure-3.2.5.jar 包下,而 Thymeleaf 框架就是內置支持的。
所以在這個包里面可以找對應的自動配置代碼,如圖:
如果找默認的屬性配置應該找XxxxProperties類,如圖所示,Thymeleaf模板的前后綴如下:
所以Thymeleaf的頁面存放在templates文件夾中,并且頁面的后綴為.html。
常用標簽:
- 數學運算
二元操作:+, - , * , / , %
一元操作: - (負)
- 邏輯運算
一元 : and or
二元 : !,not
- 比較運算(為避免轉義尷尬,可以使用括號中的英文進行比較運算!)
比較:> , < , >= ,
等于:== , != ( eq , ne )
- 簡單表達式
變量表達式: ${...}
選擇變量表達式: *{...}
消息表達式: #{...}
URL 表達式: @{...}
代碼段表達式: ~{...}
<body><!-- 使用th:text屬性輸出 --><div th:text="${message}" ></div><input type="text" th:id="${student.id}" th:name="${student.name}" th:value="${student.name}"><br/><!--循環--><table border="1"><tr><td>編號</td><td>姓名</td><td>年齡</td><td>生日</td></tr><tr th:each="student:${list}"><td th:text="${student.id}">1</td><td th:text="${student.name}">張三</td><td th:text="${student.age}">23</td><td th:text="${#dates.format(student.birthday, 'yyyy-MM-dd')}">1990-12-13</td></tr></table><!-- springmvc 保存了一個 model 對象: list --><!-- 獲取所有 list --><p th:text="${list}"></p><!-- 獲取 list 的第一個元素 --><p th:text="${list[0]}"></p><!-- 獲取第一個 student 對象的 name 屬性 --><p th:text="${list[0].name}"></p><!-- 也可以用 ['name'] 來獲取第一個 student 對象的 name 屬性 --><p th:text="${list[0]['name']}"></p><!-- 甚至可以調用方法! --><p th:text="${list[0].getName()}"></p><p th:text="${list[0]['name'].substring(0, 1)}"></p><!--判斷Thymeleaf支持四種判斷:th:if/th:unless、邏輯運算符(and、or、not)、三目運算符、switch。--><!--第一種:if & unless--><!-- 如果條件為真,執行標簽內的內容 --><div th:if="${false}">天天18</div><div th:if="${list[0].name eq '張三1'}">張三1</div><div th:if="${list[0].name == '張三1'}">張三1</div><!-- 如果條件為假,執行標簽內的內容 --><div th:unless="${false}">unless</div><!--第二種:and、or、not--><div th:if="${true or false}">真的18歲</div><div th:if="${not false}">真的別做夢</div><!--第三種:三目運算符--><span th:text="true ? '今年不是18歲' : '總算清醒了'"></span><br/><span th:text="${student.age eq 23} ? '今年是23' : '不是23'"></span><span th:text="${student.age eq 23 ? '今年23' : '不是23'}"></span><!--第四種:switch--><div th:switch="${student.age}"><div th:case="16">我今年16歲</div><div th:case="17">我今年17歲</div><div th:case="18">我今年18歲</div><div th:case="20">我今年20歲</div><div th:case="23">我今年23歲</div><div th:case="*">我年年18歲</div></div>
</body>
域對象
變量表達式的作用是:從web作用域里面取到對應的值,作用域包括 request、session、application。
@RequestMapping("/data")
public String data(HttpServletRequest request, HttpSession session) {Student student1 = new Student(1, "張三1", 23 , new Date());request.setAttribute("student1", student1);Student student2 = new Student(2, "張三2", 23, new Date());session.setAttribute("student2", student2);Student student3 = new Student(3, "張三3", 23, new Date());ServletContext application = request.getServletContext();application.setAttribute("student3", student3);return "data";
}
<body>request:<div>編號:<span th:text="${student1.id}"></span><br>姓名:<span th:text="${student1.name}"></span><br>年齡:<span th:text="${student1.age}"></span><br></div>session:<div>編號:<span th:text="${session.student2.id}"></span><br>姓名:<span th:text="${session.student2.name}"></span><br>年齡:<span th:text="${session.student2.age}"></span><br></div>application:<div>編號:<span th:text="${application.student3.id}"></span><br>姓名:<span th:text="${application.student3.name}"></span><br>年齡:<span th:text="${application.student3.age}"></span><br></div></body>
選擇變量表達式
問題:取request、session、application作用域上的屬性時,可以發現,我們需要重復編寫student1、session.student2和application.student3三次,
如果student對象的屬性有十幾個怎么辦?顯然寫十幾次相同的代碼不是我們想要解決方案。
針對這種問題,Thymeleaf提供了選擇變量表達式來解決。
request: <br/>
<div th:object="${student1}">編號: <p th:text="*{id}"></p><br/>姓名:<p th:text="*{name}"></p> <br/>年齡:<p th:text="*{age}"></p><br/>
</div>session:<br/>
<div th:object="${session.student2}">編號: <p th:text="*{id}"></p><br/>姓名:<p th:text="*{name}"></p> <br/>年齡:<p th:text="*{age}"></p><br/>
</div>
作用域內容對象的空值處理
當獲取一個作用域中不存在的對象屬性,那么會返回一個null,但是有些情況下還通過點運算符獲取對象屬性,那么這是SpringBoot會報異常。有些情況下,就是根據某個對象是否為null來執行相應的操作。
--需求:獲取session作用域中的user對象,如果不為null就輸出name,如果為null,就輸出空字符串,而不是報異常。
--分析:可以在調用對象或者方法的點(.)前面,使用問號(?)來判斷null
編號:
內置工具對象:# 符號直接使用
除了基本對象, thymeleaf 還提供了一組工具對象,其實和java中對應的方法大同小異。
@RequestMapping(value = "/util")
public String set(Model model) {Set<String> names = new HashSet<String>() ;List<Integer> ids = new ArrayList<Integer>() ;for (int i = 0 ; i < 5 ; i ++) {names.add("boot-" + i) ;ids.add(i) ;}model.addAttribute("names", names) ;model.addAttribute("ids", ids) ;model.addAttribute("mydate", new Date()) ;return "util" ;
}
<body><p th:text="${#dates.format(mydate,'yyyy-MM-dd')}"/><p th:text="${#dates.format(mydate,'yyyy-MM-dd HH:mm:ss.SSS')}"/><hr/><p th:text="${#strings.replace('www.baidu.cn','.','$')}"/><p th:text="${#strings.toUpperCase('www.baidu.cn')}"/><p th:text="${#strings.trim('www.baidu.cn')}"/><hr/><p th:text="${#sets.contains(names,'boot-0')}"/><p th:text="${#sets.contains(names,'boot-9')}"/><p th:text="${#sets.size(names)}"/><hr/><p th:text="${#lists.contains(ids,0)}"/>
</body>
Link URL
鏈接 URL 表達式語法是 @{...}
反斜杠 ”/“ 開頭,代表static目錄下的靜態資源文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" th:href="@{/bootstrap-3.3.7-dist/css/bootstrap.css}"><script type="text/javascript" th:src="@{/jquery-2.1.4.js}"></script><script type="text/javascript" th:src="@{/mylayer.js}"></script>
</head>
<body><a class="btn btn-primary" href="/">返回首頁</a> <br/><a class="btn btn-primary" href="#" th:href="@{/}">返回首頁</a> <br/><a href="/student/search">訪問StudentController下面的search方法</a> <br/><a href="#" th:href="@{/student/search}">訪問StudentController下面的search方法</a><br/><!-- 會生成 url: http://localhost:8888/student/search?id=2&name=zhangsan --><a href="#" th:href="@{/student/search(id=${student.id},name=${student.name})}">訪問UrlController下面的demo方法帶參數</a>
</body>
</html>
@Controller
@RequestMapping("/student")
public class StudentController {@RequestMapping("/search")public String search(Integer id, String name) {System.out.println("StudentController.search");System.out.println("id: " + id);System.out.println("name: " + name);return "index";}
}
如何引入另一個html頁面:
header.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div th:fragment="common_resource"><link rel="stylesheet" th:href="@{/bootstrap-3.3.7-dist/css/bootstrap.css}"><script type="text/javascript" th:src="@{/jquery-2.1.4.js}"></script><script type="text/javascript" th:src="@{/mylayer.js}"></script></div>
</body>
</html>
<head><meta charset="UTF-8"><title>Title</title><!--<link rel="stylesheet" th:href="@{/bootstrap-3.3.7-dist/css/bootstrap.css}"><script type="text/javascript" th:src="@{/jquery-2.1.4.js}"></script><script type="text/javascript" th:src="@{/mylayer.js}"></script>--><div th:replace="header::common_resource"></div>
</head>