虽然现在慢慢在流行前后端分离开发, 但是也有公司在做前后端不分离的开发, 而在前后端不分离的开发中, 我们就会需要用到后端页面模板, 可实际上, 即使是前后端分离开发, 也会有一些场景下需要使用页面模板, 例如邮件发送模板.
现在的SpringBoot页面模板主要支持Thymeleaf和Freemarker.

Thymeleaf简介

Thymeleaf是新一代Java模板引擎, 它类似于Velocity、FreeMarker等传统Java模板引擎, 但是与传统Java模板引擎不同的是, Thymeleaf支持Html原型.
它既可以让前端在浏览器中直接打开查看样式, 也可以让后端结合真实数据查看显示效果, 同时 Spring Boot提供了 Thymeleaf自动化配置解决方案, 因此在Spring Boot中使用 Thymeleaf非常方便.
Thymeleaf除了展示基本的 HTML进行页面渲染之外, 还可以作为一个 HTML片段进行渲染, 例如做邮件发送时, 可以使用 Thymeleaf作为邮件发送模板.
另外, Thymeleaf模板后缀为 .html, 可以直接被浏览器打开, 浏览非常方便.

Thymeleaf实现

Thymeleaf依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Thymeleaf配置类属性
Thymeleaf不仅仅能在Spring Boot中使用, 也可用在别的地方, 不同的是Spring Boot针对 Thymeleaf提供了一整套的自动化配置方案, 这一套配置类的属性在org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties中, 部分源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
// 默认编码
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
// 默认路径
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 = DEFAULT_PREFIX;
private String suffix = DEFAULT_SUFFIX;
private String mode = "HTML";
private Charset encoding = DEFAULT_ENCODING;
private boolean cache = true;
//...
}
  • 首先通过@ConfigurationProperties注解, 将application.properties前缀为spring.thymeleaf的配置和这个类中的属性绑定.
  • 前三个static变量定义了默认的编码格式、试图解析器的前缀和后缀等
  • 从前三行的配置中, 可以看出 Thymeleaf模板的默认位置为 resources/templates目录下, 默认的后缀是html
  • 这些配置如果开发者不自己提供, 则使用默认配置, 如果自己提供, 则在application.properties中以spring.thymeleaf开始配置

Thymeleaf自动化配置类
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration部分源码:

1
2
3
4
5
6
@Configuration
@EnableConfigurationProperties(ThymeleafProperties.class)
@ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
public class ThymeleafAutoConfiguration {
}
  • @EnableConfigurationProperties(ThymeleafProperties.class): 首先导入ThymeleafProperties
  • @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class }): 表示当当前系统中存在 TemplateMode 和 SpringTemplateEngine 类时, 当前自动化配置类才会生效, 即是只要项目中引入了 Thymeleaf相关的依赖, 这个配置便会生效
  • 这些默认的配置我们几乎不需要做任何修改就可以直接使用

Thymeleaf 实现

Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
public class IndexController {
@GetMapping("/index")
public String index(Model model) {
List<User> users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User u = new User();
u.setId((long) i);
u.setName("javaboy:" + i);
u.setAddress("深圳:" + i);
users.add(u);
}
model.addAttribute("users", users);
return "index";
}
}

model

1
2
3
4
5
6
public class User {
private Long id;
private String name;
private String address;
//省略 getter/setter
}

在IndexController中返回逻辑视图名+数据, 逻辑视图名为index, 意思就是我们需要在resources/templates目录下提供一个名为index.html的Thymeleaf的模板文件.

Thymeleaf模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1">
<tr>
<td>编号</td>
<td>用户名</td>
<td>地址</td>
</tr>
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.address}"></td>
</tr>
</table>
</body>
</html>

在Thymeleaf中, 通过th:each指令来遍历一个集合, 通过th:text指令来实现数据的展示
注意index.html的最上面要引入thymeleaf名称空间
配置完成启动项目后, 访问 /index接口, 就能看见集合中的数据

手动渲染