1. 简介

Thymeleaf 是 Java 生态中最主流的模板引擎之一,能够将后端数据无缝嵌入 HTML 页面,实现动态渲染。

本文聚焦一个常见但容易踩坑的场景:如何在 Spring Boot + Thymeleaf 的表单中正确使用隐藏输入字段(hidden inputs)。这类字段通常用于传递不可编辑的业务数据,比如记录 ID、状态标识等。

我们不会讲 Thymeleaf 基础语法,假定你已经熟悉 th:objectth: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:valueth: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 验证。


原始标题:Using Hidden Inputs with Spring and Thymeleaf