首页 / Spring Boot 入门教程 / 模板引擎 Thymeleaf

Spring Boot 入门教程

模板引擎 Thymeleaf

本教程共 48 篇 · 第 24 篇 · 更新于 2026-08-13 · 约 3 分钟阅读

Spring BootThymeleaf模板引擎服务端渲染HTML视图

本节目标:会用 Thymeleaf 在 HTML 里渲染数据、循环列表、做条件判断,并搞清什么时候该用它、什么时候该前后端分离。

模板引擎解决什么问题

页面要展示动态数据,不能写死。模板引擎的做法是:HTML 里留占位,服务端把数据填进去,渲染成完整页面再发给浏览器。

Thymeleaf 是 Spring Boot 官方推荐的模板引擎。最大特点是自然模板:模板本身是合法 HTML,直接用浏览器打开也能看,只是数据是静态的。

加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

模板文件放 src/main/resources/templates/,Spring Boot 自动识别。

第一个页面:控制器传数据

控制器往 Model 里放数据,返回视图名:

package com.example.demo.controller;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ProductPageController {

    @GetMapping("/products")
    public String products(Model model) {
        model.addAttribute("title", "商品列表");
        model.addAttribute("products", List.of(
                new Product(1L, "键盘", 199.0),
                new Product(2L, "鼠标", 99.0)));
        return "products";
    }
}

模板 templates/products.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="${title}">标题</title>
</head>
<body>
    <h1 th:text="${title}">商品列表</h1>
    <ul>
        <li th:each="product : ${products}"
            th:text="${product.name} + ' - ¥' + ${product.price}">
            商品名 - 价格
        </li>
    </ul>
</body>
</html>

访问 /productsth:each 循环渲染每个商品,th:text 替换标签内容。

Note

模板属性都带 th: 前缀。浏览器打开原文件看到的是占位内容,服务端渲染后才被替换。这就是「自然模板」的含义。

核心语法速查

输出文本th:text 转义输出,th:utext 不转义(慎用,防 XSS):

<p th:text="${user.name}">默认名字</p>

循环th:each,循环变量加 Stat 后缀能拿序号:

<tr th:each="product, stat : ${products}">
    <td th:text="${stat.count}">1</td>
    <td th:text="${product.name}">商品名</td>
</tr>

条件判断th:ifth:unless 成对用:

<p th:if="${product.price > 100}">贵</p>
<p th:unless="${product.price > 100}">便宜</p>

链接th:href 配合 @{} 写 URL,自动带上下文路径:

<a th:href="@{/products/{id}(id=${product.id})}">详情</a>

表单回填th:object 绑定对象,th:field 自动回填值:

<form th:action="@{/products}" th:object="${product}" method="post">
    <input type="text" th:field="*{name}" />
    <button type="submit">保存</button>
</form>

*{name} 是对象导航语法,等价于 ${product.name}

布局复用

每个页面都复制导航栏、页脚太笨。用 th:fragment 定义公共片段,th:replace 引用。

公共片段 templates/layout.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<body>
    <nav th:fragment="navbar">
        <a th:href="@{/}">首页</a>
        <a th:href="@{/products}">商品</a>
    </nav>
</body>
</html>

页面里引用:

<div th:replace="~{layout :: navbar}"></div>

~{文件名 :: 片段名} 定位片段。维护一处,全站生效。

与前后端分离怎么取舍

模板引擎属于服务端渲染(SSR)。后端返回完整 HTML,浏览器直接展示。前后端分离则是后端只出 JSON,前端框架自己渲染。

对比Thymeleaf 服务端渲染前后端分离
首屏速度快,一次请求拿全页面慢一点,多轮请求
SEO友好,搜索引擎能抓内容依赖预渲染
前后端协作耦合,改页面要动后端解耦,并行开发
适用场景后台管理、内容站复杂交互应用、App 接口

怎么选,看产品形态:

  • 内部管理系统、博客内容站:Thymeleaf 够用,开发快。
  • 重交互的 C 端应用、要同时服务 App:接口 + 前端框架,Thymeleaf 只做兜底页(错误页、登录页)。
  • 混合模式很常见:主功能前后端分离,管理后台用模板。
Tip

Spring Boot 4.x 对 Thymeleaf 的自动配置很完整:模板目录、缓存、编码都能用 spring.thymeleaf.* 配置调整。开发时建议 spring.thymeleaf.cache=false,改模板不用重启。

本节小结

  • Thymeleaf 是 Spring Boot 默认模板引擎,模板放 templates/。
  • th:text 输出、th:each 循环、th:if 判断、@{} 写链接。
  • th:fragment + th:replace 做布局复用。
  • 后台管理、内容站适合服务端渲染;重交互应用走前后端分离。