1. 引言
说明模版引擎,大家想必不会陌生,首先想到的就是JSP了。说起来,JSP模版引擎几乎陪伴了我从java Web从小白到熟悉的整个过程,各种标签可以说是如数家珍。但最近在用Spring Boot整项目的时候,实在无力吐槽了,本身Spring Boot并不支持JSP模版引擎,所以自己非要支持,这就很难受了。不得已而为之,只能使用Spring Boot
推荐的模版引擎之一Thymeleaf。不用不知道,一用真是感觉very nice!废话不多说,开始介绍。
2. Thymeleaf 介绍
要想了解Thymeleaf,必须官网走一波:www.thymeleaf.org/
目前最新稳定版本是Thymeleaf 3.0.11
官网上介绍就是各种NB,各种Nice,总结几点就是:
- Thymeleaf是用来开发Web和独立环境项目的服务器端的Java模版引擎
- hymeleaf与SpringMVC的视图技术,及SpringBoot的自动化配置集成非常完美,几乎没有任何成本,你只用关注Thymeleaf的语法即可。
自己在一开始接触认为最大的特点:
- Thymeleaf是html模型,它比JSP最大的优点就是不会破坏原html页面,也就是说我们可以不破坏美工设计的页面,就可以写入我们的功能。
总结了网络上大家的认为id特点:
- 动静结合:Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
- 开箱即用:它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、该jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
- 多方言支持:Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
- 与SpringBoot完美整合,SpringBoot提供了Thymeleaf的默认配置,并且为Thymeleaf设置了视图解析器,我们可以像以前操作jsp一样来操作Thymeleaf。代码几乎没有任何区别,就是在模板语法上有区别。
3. Spring Boot引入Thymeleaf
首先创建一个Spring Boot项目(使用的版本是Spring Boot 2.2.1),添加相关依赖
pom.xml
<dependencies>
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Spring Boot自动配置已经有Thymeleaf的自动配置,只有当你引入依赖之后,这些配置才会自动生效!
我们可以查看一些Thymeleaf的自动配置中已经给我们定义了读取模版文件的前缀名(位置)以及后缀名
@ConfigurationProperties(
prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING;
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 = "classpath:/templates/";
private String suffix = ".html";
private String mode = "HTML";
4. 测试实例
手写一个Controller:演示一下获取request域、session域以及ServletContext域中的内容
@Controller
public class DemoContoller {
@Autowired
private HttpSession session;
@Autowired
private ServletContext application;
@GetMapping("/test01")
public String m1(Model model){
model.addAttribute("userName","三国演义");
session.setAttribute("author","罗贯中");
application.setAttribute("createDate",new Date());
return "demo01";
}
}
将返回的对应的模版添加到默认的位置下:

这里可以演示出Thymeleaf的动静结合的好处:
比如我的demo01是这样定义的:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"> //注意必须引入,否则没有提示
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${userName}">西游记</h1>
</body>
</html>
如果是一个静态的文件打开显示的是西游记:


<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- <h1 th:text="${userName}">西游记</h1>-->
<h2>request的获取方式</h2>
<h1 th:text="${userName}+','+${userName}" ></h1>
<h1 th:text="|${#request.getAttribute('userName')},${#request.getAttribute('userName')}|" ></h1>
<h2>session的获取方式</h2>
<span th:text="|${session.author},${session['author']},${#httpSession.getAttribute('author')}|"></span>
<h2>application的获取方式</h2>
<span th:text="${application.createDate}"></span>
<span th:text="${#servletContext.getAttribute('createDate')}"></span>
<span th:text="${application['createDate']}"></span>
</body>
</html>

5.Thymeleaf 常用用法
如上面可以使用一些基本的标签获取数据,这里要提醒的是大家不要意味${}是EL表达式,而是ognl表达式,两者用法非常像!常用用法:
- 对上面从ServletContext中取到的日期进行格式化
<input type="text" th:value="${#dates.format(application.createDate)}">
- 操作对象
Entity:
public class User {
private Integer userId;
private String userName;
private Integer userAge;
private Integer userSex;
private String[] hobbyArray;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
public Integer getUserSex() {
return userSex;
}
public void setUserSex(Integer userSex) {
this.userSex = userSex;
}
public String[] getHobbyArray() {
return hobbyArray;
}
public void setHobbyArray(String[] hobbyArray) {
this.hobbyArray = hobbyArray;
}
}
Controller:
@GetMapping("/test02")
public String m2(Model model){
User user=new User();
user.setUserId(999);
user.setUserName("悟空");
user.setUserAge(50);
user.setUserSex(1);
user.setHobbyArray(new String[]{"篮球","足球","音乐"});
model.addAttribute("user",user);
return "demo02";
}
Thymeleaf模版页面:
<h1>显示数据的方式</h1>
<ul>
<li th:text="${user.userName}"></li>
//单选框的选择上
<li th:if="${user.userSex==1}">男生</li>
<li th:unless="${user.userSex==1}">女生</li>
</ul>
<ol th:object="${user}">
<li th:text="*{userName}"></li>
<li th:if="*{userSex==1}">男生</li>
<li th:unless="*{userSex==1}">女生</li>
</ol>
<select name="" id="">
//遍历
<option value="" th:each="hobby,vs:${user.hobbyArray}" th:value="|${vs.index},${vs.count}|" th:text="${hobby}"></option>
</select>
<h1>[[${user.userName}]]</h1>
//javascript取数据
<script>
var name='[[${user.userName}]],[[${user.userSex}]]'
alert(name);
</script>
- 其他用法
其他用法用到的时候自行查阅,一般直接看官网文档就可以的!