SpringBoot整合Thymeleaf模板引擎的实战指南

 更新时间:2026年07月07日 09:03:53   作者:张老师技术栈  
本文介绍了如何在SpringBoot项目中集成Thymeleaf模板引擎,包括添加Maven依赖,配置application.properties,以及创建简单的Controller和HTML模板,实现动态数据展示,需要的朋友可以参考下

SpringBoot 不推荐用 JSP,官方推荐的模板引擎是 Thymeleaf。这篇讲 Thymeleaf 的核心语法和实际项目中的最佳实践。

一、为什么用 Thymeleaf 而不是 JSP

对比ThymeleafJSP
语法标准 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/html

3. 目录结构

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内置tomcat调优测试优化

    SpringBoot内置tomcat调优测试优化

    这篇文章主要介绍了SpringBoot内置tomcat调优测试优化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • minio分布式文件管理方式

    minio分布式文件管理方式

    文章介绍了MinIO作为分布式存储系统,支持大文件存储与数据恢复,通过Docker部署并配置多副本存储,同时涵盖图片/视频上传、断点续传、格式转换(如AVI转MP4)及xxl-job分布式任务调度,强调乐观锁机制和补偿机制确保任务可靠性与数据一致性
    2025-08-08
  • SpringBoot实现前后端、json数据交互以及Controller接收参数的几种常用方式

    SpringBoot实现前后端、json数据交互以及Controller接收参数的几种常用方式

    这篇文章主要给大家介绍了关于SpringBoot实现前后端、json数据交互以及Controller接收参数的几种常用方式,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-03-03
  • java 防盗链详解及解决办法

    java 防盗链详解及解决办法

    这篇文章主要介绍了 java 防盗链详解及解决办法的相关资料,这里介绍了防盗链的概念、产生原因及Http中的referer,最后介绍解决办法,需要的朋友可以参考下
    2017-07-07
  • intellij idea如何配置网络代理

    intellij idea如何配置网络代理

    intellij idea所在的这台电脑本身上不了网,要通过代理上网,那么intellij idea怎么设置代理上网呢?今天通过本文给大家分享intellij idea如何配置网络代理,感兴趣的朋友一起看看吧
    2023-10-10
  • java web手写实现分页功能

    java web手写实现分页功能

    这篇文章主要为大家详细介绍了java web手写实现分页功能的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • SpringBoot 使用@WebMvcTest测试MVC Web Controller

    SpringBoot 使用@WebMvcTest测试MVC Web Controller

    这篇文章主要介绍了SpringBoot 使用@WebMvcTest测试MVC Web Controller,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java中的5种同步辅助类介绍

    Java中的5种同步辅助类介绍

    你提交了一些任务,但你想等它们都完成了再做另外一些事情;你提交了一些任务,但是不想让它们立刻执行,等你喊123开始的时候,它们才开始执行;等等这些场景,线程之间需要相互配合,或者等待某一个条件成熟执行。这些场景想你就需要用到同步辅助类
    2014-04-04
  • Java在PDF中替换文字详解及可能遇到的问题

    Java在PDF中替换文字详解及可能遇到的问题

    本文详细介绍了如何使用Java和Spire.PDF for Java库在PDF文档中批量替换文字,包括替换特定文字的所有实例、第一个实例以及使用正则表达式,同时,探讨了可能遇到的问题及其解决方案,需要的朋友可以参考下
    2024-09-09
  • SpringBoot项目微信云托管入门部署实践

    SpringBoot项目微信云托管入门部署实践

    本文主要介绍了SpringBoot项目微信云托管入门部署实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03

最新评论