Thymeleaf也是一款模板引擎,但它不依赖标签库,是SpringBoot官方推荐的模板引擎,使用也比较广泛
一、项目配置
1. 导入依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- <version>2.4.5</version>
- </dependency>
2. 新建html
在templates目录下新建html:

内容为:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- hello thymeleaf
- </body>
- </html>
3. Controller中新建接口
和FreeMarker一样,Thymeleaf不支持直接访问
- @Controller
- public class MyController {
-
- @RequestMapping("hello")
- public String hello() {
- return "hello";
- }
-
- }
浏览器访问:

二、标准变量表达式
标准变量表达式就是Thpmeleaf完成数据的展示和处理的方式,必须在标签中使用,使用th命名空间,语法为:<tag th:xx="${key}"></tag>
新建test.html:

1. th:text
对应text属性,从Controller层返回一个数据:
- @RequestMapping("test")
- public String test(Model model) {
- model.addAttribute("msg","controller msg");
- return "test";
- }
html修改为:
- <!doctype html>
- <html lang="en" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8">
- </head>
- <body>
- <span th:text="123"></span>
- </body>
- </html>
访问结果:

2. th:value
对应input的value属性
<input th:value="${msg}">

3. th:if
可以进行if判断来是否显示该标签
<p th:if="${name}!='张三'">hello</p>

4. th:each
用于遍历list集合,语法为:th:each="obj,index:${listName}"
- index : 索引对象,包含索引、数据量大小、序号等
- obj:遍历到的单个对象
- listName:controller层传递的集合参数名
内部标签就可以使用上面对象
使用之前SpringBoot--配置MyBatis、Logback、PagerHelper、Druid中的员工集合代码,将员工显示到页面上
controller层代码和之前一样:
- @RequestMapping("showEmpList")
- public ModelAndView showEmpList(ModelAndView modelAndView) {
- List<Emp> allEmpList = empService.findAllEmp();
- modelAndView.setViewName("showEmpList");
- Map<String, Object> model = modelAndView.getModel();
- model.put("empList", allEmpList);
-
- return modelAndView;
- }
html代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <style>
- #empTable {
- margin: 0 auto;
- border: 1px solid antiquewhite;
- width: 80%;
- }
-
- #empTable th, td {
- border: 1px solid bisque;
- text-align: center;
- }
-
- </style>
- </head>
- <body>
- <table id="empTable" cellpadding="0px" cellspacing="0px">
- <tr>
- <th>索引</th>
- <th>员工编号</th>
- <th>姓名</th>
- <th>职位</th>
- <th>上级</th>
- <th>薪水</th>
- <th>奖金</th>
- <th>部门编号</th>
- </tr>
-
- <tr th:each="emp,i:${empList}">
- <td th:text="${i.index}"></td>
- <td th:text="${emp.empno}"></td>
- <td th:text="${emp.ename}"></td>
- <td th:text="${emp.job}"></td>
- <td th:text="${emp.mgr}"></td>
- <td th:text="${emp.sal}"></td>
- <td th:text="${emp.comm}"></td>
- <td th:text="${emp.deptno}"></td>
- </tr>
- </table>
- </body>
- </html>
效果:

5. 运算符
5.1 基本运算符
标准表达式中支持基本的运算符:+、-、*、/、%
<td th:text="${i.index + 1}"></td>
5.2 关系运算符
关系运算符还是推荐使用转义:
符号 | 转义后 |
---|---|
> | gt |
>= | ge |
< | lt |
<= | le |
== | eq |
!= | ne |
5.3 逻辑运算符
- 并且:&&、and
- 或者: ||、or
5.4 三目运算符
和java相同的写法:[expression]?value1:value2
5.5 动态修改style属性
结合上面的运算符,动态修改style属性:
<td th:text="${emp.sal}" th:style="${emp.sal} ne null and ${emp.sal} gt 2000? 'color:red':''"></td>
效果:

6. th:href
用于设置a标签的href属性,语法:th:href="@{function(param1=${},param2=${}, ..)}"
实现删除员工的功能
定义Mapper:
- @Mapper
- public interface EmpMapper {
- ...
- int deleteEmp(Integer empno, String ename);
- }
映射文件:
- <!--int deleteEmp(Integer empno, String ename);-->
- <delete id="deleteEmp">
- delete from emp where empno = #{empno} and ename = #{ename}
- </delete>
service对应的进行编写,这边就不贴出代码了,controller新增处理单元:
- @RequestMapping("deleteEmpByNoAndName")
- public String deleteEmpByNoAndName(Integer empno, String ename) {
- boolean success = empService.deleteEmpByNoAndName(empno, ename);
- return "redirect:/showEmpList";
- }
html中使用:
<a th:href="@{deleteEmpByNoAndName(empno=${emp.empno},ename=${emp.ename})}">删除</a>
效果:

7. th:onclick
绑定点击事件,语法:th:οnclick="function( [[param1]], [[param2]], ..)"
实现点击删除后有一个提示
html:
- <a href="javascript:void(0)" th:onclick="removeEmpByNoAndName([[${emp.empno}]],[[${emp.ename}]])">删除</a>
-
- <script>
- function removeEmpByNoAndName(empno, ename) {
- var ret = confirm("确定删除员工编号为:" + empno + "的" + ename)
- if (ret) {
- window.location.href = "deleteEmpByNoAndName?empno=" + empno + "&ename=" + ename
- }
- }
- </script>
效果:

三、内置对象
Thymeleaf也内置了一些工具类:

作用:
#arrays:数组操作的工具;
#aggregates:操作数组或集合的工具;
#bools:判断boolean类型的工具;
#calendars:类似于#dates,但是是java.util.Calendar类的方法;
#ctx:上下文对象,可以从中获取所有的thymeleaf内置对象;
#dates:日期格式化内置对象,具体方法可以参照java.util.Date;
#numbers: 数字格式化;#strings:字符串格式化,具体方法可以参照String,如startsWith、contains等;
#objects:参照java.lang.Object;
#lists:列表操作的工具,参照java.util.List;
#sets:Set操作工具,参照java.util.Set;#maps:Map操作工具,参照java.util.Map;
#messages:操作消息的工具。
1. string对象
方法名 | 描述 |
---|---|
#string.isEmpty(key) | 判断字符串是否为空,为空返回true,反之false |
#string.contains(msg,'T') | 判断字符串是否包含T的子串,包含返回true,反之false |
#string.startsWith(msg,'a') | 判断字符串是否以a子串为开始,为开始返回true,反之false |
#string.endsWith(msg,'a') | 判断字符串是否以a子串为结束,为结束返回true,反之false |
#string.length(msg) | 返回字符串大小 |
#string.indexOf(msg,'a') | 查找字符串中包含a子串的第一个下标,包含返回下标,反之-1 |
2. dates对象
方法名 | 描述 |
---|---|
#dates.format(key) | 格式化日期,默认以浏览器语言为标准 |
#dates.format(key,'yyyy-MM-dd') | 自定义格式化日期 |
#dates.year(key) | 获取年 |
#dates.month(key) | 获取月 |
#dates.day(key) | 获取日 |
html中显示员工入职日期:
<td th:text="${!#strings.isEmpty(emp)?#dates.format(emp.hiredate,'yyyy-MM-dd'):''}"></td>

3. 域对象
controller中新增:
- @RequestMapping("showEmpList")
- public ModelAndView showEmpList(ModelAndView modelAndView, HttpServletRequest req, HttpSession session) {
- List<Emp> allEmpList = empService.findAllEmp();
- modelAndView.setViewName("showEmpList");
- Map<String, Object> model = modelAndView.getModel();
- model.put("empList", allEmpList);
-
- // 向request域放数据
- req.setAttribute("msg", "requestMessage");
- // 向session域放数据
- session.setAttribute("msg", "sessionMessage");
- // 向application域放数据
- req.getServletContext().setAttribute("msg", "applicationMessage");
-
- return modelAndView;
- }
html中获取传递的域数据:
- httpServletRequest:
- <span th:text="${#httpServletRequest.getAttribute('msg')}"></span>
- <span th:text="${#request.getAttribute('msg')}"></span>
- <hr/>
-
- httpSession:
- <span th:text="${#httpSession.getAttribute('msg')}"></span>
- <span th:text="${#session.getAttribute('msg')}"></span>
- <span th:text="${session.msg}"></span>
- <hr/>
-
- servletContext:
- <span th:text="${#servletContext.getAttribute('msg')}"></span>
- <span th:text="${application.msg}"></span>
- <hr/>
效果:
