SpringBoot整合Thymeleaf模板引擎的实战指南
更新时间:2026年07月07日 09:03:53 作者:张老师技术栈
本文介绍了如何在SpringBoot项目中集成Thymeleaf模板引擎,包括添加Maven依赖,配置application.properties,以及创建简单的Controller和HTML模板,实现动态数据展示,需要的朋友可以参考下
SpringBoot 不推荐用 JSP,官方推荐的模板引擎是 Thymeleaf。这篇讲 Thymeleaf 的核心语法和实际项目中的最佳实践。
一、为什么用 Thymeleaf 而不是 JSP
| 对比 | Thymeleaf | JSP |
|---|---|---|
| 语法 | 标准 HTML,浏览器可直接打开 | 需要服务器解析 |
| 前后端分离 | 天然支持 HTML 属性语法 | 耦合度高 |
| 与 SpringBoot 集成 | ✅ 原生支持 | ❌ 需要额外配置 |
| 国际化 | ✅ 内置支持 | ✅ 支持 |
| 性能 | 缓存后性能好 | 一般 |
二、基础配置
1. 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>2. 配置
spring:
thymeleaf:
cache: false # 开发时关闭缓存
prefix: classpath:/templates/
suffix: .html
mode: HTML
encoding: utf-8
servlet:
content-type: text/html3. 目录结构
src/main/resources/templates/
├── fragments/ # 公共片段
│ ├── header.html
│ └── footer.html
├── layout/ # 布局模板
│ └── base.html
├── index.html # 页面
├── product.html
└── error/
├── 404.html
└── 500.html三、核心语法
1. 变量取值
<!-- Controller 传值 -->
<p th:text="${message}">默认文本</p>
<p th:text="${user.name}">张三</p>
<p th:text="${user.age > 18 ? '成年' : '未成年'}">成年</p>
<!-- 对象属性 -->
<div th:object="${user}">
<p th:text="*{name}">姓名</p>
<p th:text="*{age}">年龄</p>
</div>2. 条件判断
<!-- if-unless -->
<p th:if="${user != null}">用户已登录</p>
<p th:unless="${user != null}">未登录</p>
<!-- switch-case -->
<div th:switch="${user.role}">
<p th:case="'admin'">管理员</p>
<p th:case="'user'">普通用户</p>
<p th:case="*">未知角色</p>
</div>3. 循环遍历
<table>
<thead>
<tr>
<th>序号</th>
<th>名称</th>
<th>价格</th>
</tr>
</thead>
<tbody>
<tr th:each="product, stat : ${productList}">
<td th:text="${stat.count}">1</td>
<td th:text="${product.name}">商品名</td>
<td th:text="${#numbers.formatDecimal(product.price, 0, 2)}">0.00</td>
</tr>
</tbody>
</table>循环状态变量:
stat.index → 从 0 开始的索引 stat.count → 从 1 开始的计数 stat.size → 总数量 stat.first → 是否是第一个 stat.last → 是否是最后一个 stat.odd → 是否是奇数行 stat.even → 是否是偶数行
4. URL 链接
<!-- 绝对路径 -->
<script th:src="@{/js/app.js}"></script>
<link th:href="@{/css/style.css}" rel="external nofollow" rel="external nofollow" rel="stylesheet"/>
<!-- 带参数 -->
<a th:href="@{/product/detail(id=${product.id})}" rel="external nofollow" >详情</a>
<!-- 多参数 -->
<a th:href="@{/product/list(page=${page}, size=20)}" rel="external nofollow" >下一页</a>
<!-- RESTful 风格 -->
<a th:href="@{/product/{id}(id=${product.id})}" rel="external nofollow" >详情</a>四、布局与组件复用
1. 定义布局模板 (layout/base.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title th:text="${title}">默认标题</title>
<link th:href="@{/css/style.css}" rel="external nofollow" rel="external nofollow" rel="stylesheet"/>
</head>
<body>
<!-- 顶部导航 -->
<div th:replace="fragments/header :: header"></div>
<!-- 页面主体内容 -->
<div layout:fragment="content">
默认内容
</div>
<!-- 底部 -->
<div th:replace="fragments/footer :: footer"></div>
</body>
</html>2. 公共片段 (fragments/header.html)
<div th:fragment="header">
<nav>
<a th:href="@{/}" rel="external nofollow" rel="external nofollow" >首页</a>
<a th:href="@{/product/list}" rel="external nofollow" >商品</a>
<a th:href="@{/about}" rel="external nofollow" >关于</a>
</nav>
</div>3. 子页面使用布局
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/base}">
<!-- 只需填写内容部分 -->
<div layout:fragment="content">
<h1 th:text="${product.name}">商品名称</h1>
<p th:text="'¥' + ${product.price}">价格</p>
</div>五、表单处理
<form th:action="@{/product/save}" th:object="${product}" method="post">
<input type="hidden" th:field="*{id}"/>
<label>名称:</label>
<input type="text" th:field="*{name}"/>
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">错误提示</p>
<label>价格:</label>
<input type="text" th:field="*{price}"/>
<label>分类:</label>
<select th:field="*{category}">
<option th:each="cat : ${categories}"
th:value="${cat}"
th:text="${cat}">分类</option>
</select>
<button type="submit">提交</button>
</form>六、内置工具方法
<!-- 日期格式化 -->
<p th:text="${#dates.format(now, 'yyyy-MM-dd HH:mm:ss')}">2026-07-06</p>
<!-- 数字格式化 -->
<p th:text="${#numbers.formatDecimal(price, 0, 2)}">0.00</p>
<!-- 字符串截断 -->
<p th:text="${#strings.abbreviate(description, 50)}">描述</p>
<!-- 集合大小 -->
<p th:text="${#lists.size(productList)}">0</p>
<!-- 是否包含 -->
<p th:if="${#strings.contains(name, '手机')}">手机类商品</p>
<!-- 生成随机数 -->
<p th:text="${#uris.escapePath(uri)}">编码后URL</p>七、秒杀系统页面整合
<!-- product/list.html -->
<html layout:decorate="~{layout/base}">
<div layout:fragment="content">
<h1>秒杀商品列表</h1>
<div class="product-grid">
<div class="card" th:each="p : ${products}">
<h3 th:text="${p.productName}">名称</h3>
<p class="desc" th:text="${p.productDesc}">描述</p>
<span class="original" th:text="'¥' + ${p.price}">原价</span>
<span class="seckill" th:text="'¥' + ${p.seckillPrice}">秒杀价</span>
<button th:attr="data-id=${p.id}"
th:disabled="${p.stock <= 0}"
onclick="doSeckill(this)">
立即抢购
</button>
</div>
</div>
</div>
</html>八、错误页面
SpringBoot 自动识别 templates/error/ 下的页面:
<!-- error/404.html -->
<!DOCTYPE html>
<html>
<head><title>404</title></head>
<body>
<h1>404 - 页面未找到</h1>
<p th:text="${error}">错误信息</p>
<a th:href="@{/}" rel="external nofollow" rel="external nofollow" >返回首页</a>
</body>
</html>九、性能优化
spring:
thymeleaf:
cache: true # 生产开启缓存
check-template-location: true
cacheable: true总结
Thymeleaf 的核心套路:
取值:th:text / th:value 条件:th:if / th:unless 循环:th:each 链接:th:href / th:src 布局:layout:decorate / th:replace 表单:th:object / th:field
对于秒杀系统这种前后端不分离的项目,Thymeleaf 完全够用,而且开发效率比前后端分离高。
以上就是SpringBoot整合Thymeleaf模板引擎的实战指南的详细内容,更多关于SpringBoot整合Thymeleaf模板引擎的资料请关注脚本之家其它相关文章!
相关文章
SpringBoot实现前后端、json数据交互以及Controller接收参数的几种常用方式
这篇文章主要给大家介绍了关于SpringBoot实现前后端、json数据交互以及Controller接收参数的几种常用方式,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2022-03-03
SpringBoot 使用@WebMvcTest测试MVC Web Controller
这篇文章主要介绍了SpringBoot 使用@WebMvcTest测试MVC Web Controller,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-11-11


最新评论