前言
SpringBoot 整合 Thymeleaf。
实现
理论
Thymeleaf 是一个优秀的、面向 Java 的 HTML 页面模板,具有丰富的标签语言和函数。在 JSP 被淘汰之后,Thymeleaf 取而代之成为了 Spring Boot 推荐的模板引擎。
Thymeleaf 在有网和没网的环境下都可以正常工作,既能让美工在浏览器中查看页面的静态效果,也能让程序员在服务器查看带数据的动态页面效果。
这是因为 Thymeleaf 支持 HTML 原型,在 HTML 标签里增加额外的属性来达到模板+数据的展示方式。
浏览器在解释 HTML 的时候会忽略未定义的标签属性,所以 Thymeleaf 可以静态地运行;当有数据返回页面时,Thymeleaf 标签会动态地替换静态内容。

下面列举一些 Thymeleaf 常用的表达式、标签和函数。
1)常用表达式
${...}变量表达式*{...}选择表达式#{...}文字表达式@{...}URL表达式#maps对象表达式
2)常用标签
th:action定义服务器端控制器路径th:each循环语句th:field表单字段th:href URL链接th:id div标签中的 IDth:if条件判断th:include引入文件th:fragment定义代码片段th:object替换对象th:src图片地址th:text文本th:value属性值
3)常用函数
#dates日期函数#lists列表函数#arrays数组函数#strings字符串函数#numbers数字函数#calendars日历函数#objects对象函数#bools布尔函数
想要查看更多 Thymeleaf 表达式、标签、函数等内容,可以到 Thymeleaf 官网。
SpringBoot
创建 SpringBoot 项目。此项目的数据持久层框架我们仍然使用 JPA 实现。
pom.xml
在 pom.xml 中导入如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
application.properties
在 application.properties 中添加如下配置项:
# 开发时关闭缓存,不然看不到实时页面
spring.thymeleaf.cache=false
spring.datasource.username=root
spring.datasource.password=
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
# 开启JPA的SQL输出
spring.jpa.show-sql=true
User实体类
创建 User 实体类。
package com.langjialing.thymeleafdemo.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author 郎家岭伯爵
* @time 2023/7/14 9:34
*/
@Data
@Entity
@Table(name = "user")
public class User {
@Id
private Integer userId;
private Integer age;
private String userName;
private String password;
}
UserRepository接口类
创建 UserRepository 接口类,并继承 JpaRepository 类。
package com.langjialing.thymeleafdemo.repository;
import com.langjialing.thymeleafdemo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/7/14 9:35
*/
public interface UserRepository extends JpaRepository<User, Integer> {
/**
* 自定义查询方法
* @param name name
* @return List
*/
@Query("select u from User u where u.userName like concat('%',?1,'%')")
List<User> findByNameLikeIgnoreCase(String name);
}
service层
UserService 接口类:
package com.langjialing.thymeleafdemo.service;
import com.langjialing.thymeleafdemo.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/7/14 9:37
*/
public interface UserService {
/**
* 根据ID查询单个用户。
* @param id id
* @return user
*/
User findById(Integer id);
/**
* 查找所有用户。
* @return List
*/
List<User> findAll();
/**
* 新增/更新用户。
* @param user user
* @return User
*/
User save(User user);
/**
* 根据ID删除用户。
* @param id ID
*/
void delete(Integer id);
/**
* 查询所有用户(分页)。
* @param pageable 分页参数
* @return Page
*/
Page<User> findAll(Pageable pageable);
/**
* 根性名字查询用户。
* @param name name
* @return List
*/
List<User> findByNameLikeIgnoreCase(String name);
}
UserServiceImpl 接口实现类:
package com.langjialing.thymeleafdemo.service.impl;
import com.langjialing.thymeleafdemo.entity.User;
import com.langjialing.thymeleafdemo.repository.UserRepository;
import com.langjialing.thymeleafdemo.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/7/14 9:38
*/
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserRepository userRepository;
@Override
public User findById(Integer id) {
return userRepository.findById(id).orElse(null);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public User save(User user) {
return userRepository.save(user);
}
@Override
public void delete(Integer id) {
userRepository.deleteById(id);
}
@Override
public Page<User> findAll(Pageable pageable) {
return userRepository.findAll(pageable);
}
@Override
public List<User> findByNameLikeIgnoreCase(String name) {
return userRepository.findByNameLikeIgnoreCase(name);
}
}
controller层
创建 controller 控制器层:
package com.langjialing.thymeleafdemo.controller;
import com.langjialing.thymeleafdemo.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
/**
* @author 郎家岭伯爵
* @time 2023/7/14 10:12
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@RequestMapping("/all")
public String all(Model model) {
model.addAttribute("users", userService.findAll());
return "all";
}
}
@Controller注解表示该类为一个控制器类。@RequestMapping注解用来处理请求地址映射,可用于类或者方法。Model接口可以承载数据库里查到的数据,前端可以从 model 中取出来。
HTML文件
Thymeleaf 模板引擎默认会读取 resources 目录下的 templates 目录,这个目录是用来存放 HTML 页面的。
在 resources/templates 目录下新建 all.html 文件(文件名对应控制器中 all 方法返回的字符串)。
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Thymeleaf</title>
</head>
<body>
<table>
<tr>
<td>用户名</td>
<td>密码</td>
</tr>
<tr th:each="user:${users}">
<td th:text="${user.userName}"></td>
<td th:text="${user.password}"></td>
</tr>
</table>
</body>
</html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org"> 为 Thymeleaf 的命名空间,通过引入命名空间就可以在 HTML 文件中使用 Thymeleaf 标签语言,用关键字 th 来标注。
测试效果

在浏览器地址栏输入 http://localhost:8080/user/all 地址:

总结
SpringBoot 整合 Thymeleaf。