1. 简介
Thymeleaf 是 Java 生态中最主流的模板引擎之一,能够将后端数据无缝嵌入 HTML 页面,实现动态渲染。
本文聚焦一个常见但容易踩坑的场景:如何在 Spring Boot + Thymeleaf 的表单中正确使用隐藏输入字段(hidden inputs)。这类字段通常用于传递不可编辑的业务数据,比如记录 ID、状态标识等。
我们不会讲 Thymeleaf 基础语法,假定你已经熟悉 th:object
、th:field
这些核心机制。
2. Thymeleaf 与 HTML 表单的绑定机制
在深入隐藏字段前,先回顾下 Thymeleaf 表单的基本工作方式。
✅ 最典型场景是:HTML 表单字段直接绑定到 Java DTO 的属性上。
举个例子,假设我们正在开发一个博客系统,有如下 DTO:
class BlogDTO {
long id;
String title;
String body;
String category;
String author;
Date publishedDate;
}
使用 Thymeleaf 可以这样构建表单:
<form action="#" method="post" th:action="@{/blog}" th:object="${blog}">
<input type="text" th:field="*{title}" />
<input type="text" th:field="*{category}" />
<textarea th:field="*{body}"></textarea>
</form>
📌 关键点:
th:object="${blog}"
指定绑定对象*{xxx}
表示从该对象中取属性- 提交时,Spring MVC 会自动将表单参数映射回
BlogDTO
实例
⚠️ 但问题来了:某些字段(如 id
)不应该由用户修改,但仍需随表单提交。这时候就需要隐藏字段。
3. 使用 th:field
设置隐藏字段(推荐)
最简洁的方式是直接用 th:field
创建隐藏输入:
<input type="hidden" th:field="*{id}" id="blogId" />
✅ 优点:
- 写法简单粗暴
- 自动处理 name、value、绑定逻辑
- 与表单其他字段风格统一
❌ 注意:
- 要求 Thymeleaf 3.0+ 版本支持
- 如果你还在用老项目(Thymeleaf 2.x),可能不兼容
💡 小贴士:Spring Boot 2.x 默认集成 Thymeleaf 3,基本不用顾虑版本问题。
4. 使用 th:attr
显式设置属性
如果你需要更细粒度控制,或者出于兼容性考虑,可以用 th:attr
手动构造:
<input type="hidden" th:value="${blog.id}" th:attr="name='id'" />
📌 解析:
th:value
绑定值th:attr
设置name
属性为id
,确保后端能正确绑定- 注意这里必须通过
${blog.id}
显式引用对象属性
⚠️ 缺点:写法啰嗦,容易漏掉 name
导致绑定失败。
5. 直接使用 HTML name
属性(轻量级方案)
更简洁的做法是混合使用标准 HTML 属性和 Thymeleaf 表达式:
<input type="hidden" th:value="${blog.id}" name="id" />
✅ 优点:
- 无需
th:attr
,代码更清爽 - 兼容所有 Thymeleaf 版本
name="id"
确保 Spring 能正确反序列化到 DTO 的id
字段
📌 原理:Spring MVC 绑定时只关心 name
是否匹配 DTO 属性名,不管是不是 hidden。
✅ 推荐用于简单场景,尤其是只传一两个只读字段时。
6. 总结对比
方式 | 是否推荐 | 适用场景 |
---|---|---|
th:field="*{id}" |
✅ 强烈推荐 | Thymeleaf 3+,追求一致性 |
th:attr + th:value |
⚠️ 可用但繁琐 | 需要动态设置多个属性 |
name + th:value |
✅ 推荐 | 兼容性要求高、轻量使用 |
📌 核心原则:
- 隐藏字段本质还是表单参数,关键是
name
和值都要正确传递 - 不要手动拼接 value,始终用
th:value
或th:field
防止 XSS - DTO 中的
id
字段建议设为Long
而非long
,避免新建记录时默认传 0
附录:完整示例代码
GitHub 仓库地址:https://github.com/example/spring-thymeleaf-demo
包含以下内容:
BlogDTO.java
BlogController.java
edit-blog.html
(含三种 hidden input 写法)
所有示例均已通过 Spring Boot 3 + Thymeleaf 3.1 验证。