在Spring Boot单体应用里,让后端直接渲染HTML页面可以显著降低联调复杂度。Thymeleaf凭借自然的HTML原型特性,成为官方默认支持的模板引擎。它通过标准方言把模型数据绑定到DOM节点,开发者写出的模板在浏览器中也能作为静态页预览。

一、项目依赖与基础配置
要在Spring Boot中启用Thymeleaf,首先引入起步依赖。该依赖会自动配置视图解析器,默认指向src/main/resources/templates目录下的模板文件,静态资源则放在src/main/resources/static中。
引入依赖后通常无需过多配置,但了解关键属性有助于排查问题。例如spring.thymeleaf.prefix定义模板路径,spring.thymeleaf.suffix定义文件后缀,spring.thymeleaf.cache在生产环境应开启,开发时建议关闭以便热更新。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
下面是一段常见的开发环境配置,关闭缓存并启用严格模式,可以避免模板语法错误被忽略:
spring.thymeleaf.cache=false spring.thymeleaf.mode=HTML spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html
二、控制器与模型数据传递
Spring Boot的控制器通过Model对象向模板传递数据。在方法参数中声明Model,调用addAttribute即可把后端对象暴露给Thymeleaf。返回的字符串对应模板文件名,视图解析器会自动拼接前后缀找到页面。
这种机制让前后端共用同一份路由:浏览器请求/user/list,控制器查询数据库后将集合放入模型,模板遍历渲染表格。相比纯接口返回JSON,省去了前端再写请求与状态管理的代码。
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/list")
public String list(Model model) {
List<String> users = Arrays.asList("Alice", "Bob", "Charlie");
model.addAttribute("users", users);
model.addAttribute("title", "用户列表");
return "user/list";
}
}
模板中通过th:text等属性读取模型。注意Thymeleaf属性会覆盖原生HTML内容,因此即使静态打开也能看到占位文字,而运行时被真实数据替换。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="${title}">默认标题</title>
</head>
<body>
<ul>
<li th:each="u : ${users}" th:text="${u}">用户名</li>
</ul>
</body>
</html>
三、表单绑定与后端校验
Thymeleaf对表单的支持极为友好,使用th:object绑定命令对象,th:field自动生成name、id及值回填。结合Spring的@Valid校验,可以把错误信息直接通过th:errors展示在对应字段旁。
这种方式的优势在于:用户提交失败后,输入框中已填内容不会丢失,因为Thymeleaf从模型对象重新渲染。同时后端校验规则复用同一实体类,避免前后端重复定义约束。
@PostMapping("/save")
public String save(@Valid @ModelAttribute UserForm form, BindingResult result, Model model) {
if (result.hasErrors()) {
return "user/form";
}
// 保存逻辑
return "redirect:/user/list";
}
对应的模板片段如下,th:errors会在校验失败时输出提示,th:value负责回显:
<form th:action="@{/user/save}" th:object="${userForm}" method="post">
<input type="text" th:field="*{name}" />
<span th:errors="*{name}">名称错误</span>
<button type="submit">提交</button>
</form>
四、静态资源与片段复用
在模板中引用CSS或JS时,使用th:href与th:src配合@{}语法,Spring Boot会自动映射到static目录。这样无论应用上下文路径如何变化,资源地址都不会写死。
另一个提升效率的特性是片段(Fragment)。通过th:fragment定义公共头部或底部,再用th:replace引入,避免每个页面重复粘贴布局代码,也方便统一修改。
<head>
<link rel="stylesheet" th:href="@{/css/main.css}" />
</head>
<body>
<div th:replace="~{layout/header :: header}"></div>
<div th:fragment="content">页面主体</div>
</body>
片段不仅可以静态包含,还能传参。例如把当前菜单名传入头部片段,高亮对应导航项,使模板之间既解耦又灵活。
五、国际化与多环境适配
Thymeleaf结合Spring的MessageSource可以轻松实现多语言。模板中用#{key}读取文案,后端根据请求头或会话区域解析对应属性文件,无需改动页面结构。
在微服务或内外网部署时,还可利用th:if等条件表达式控制元素显示。例如内网环境展示调试信息,外网隐藏,保持同一套模板适应不同场景,降低维护分支成本。
<p th:text="#{welcome.msg}">欢迎</p>
<span th:if="${env == 'internal'}">内部调试入口</span>
整体来看,Spring Boot与Thymeleaf的协同并非简单套模板,而是借助约定优于配置的理念,把路由、数据绑定、校验、布局整合到一条清晰的开发链路中。对于中小型系统或内部工具,这种集成方式能让你用更少代码交付完整可用的界面。
Spring_BootThymeleaf前后端集成修改时间:2026-08-08 12:30:35