当前位置: 首页 > news >正文

Thymeleaf 表单绑定与验证详解

关键词:Thymeleaf、Spring Boot、表单绑定、数据绑定、后端验证、@ValidBindingResult、错误提示


✅ 引言

在 Web 开发中,表单提交与数据验证是用户交互中最常见的场景之一。Thymeleaf 作为 Spring Boot 默认支持的模板引擎,提供了强大的表单绑定机制和错误提示功能,能够无缝对接 Spring MVC 的后端验证逻辑。

本文将围绕 Thymeleaf 表单绑定与验证 进行系统讲解,涵盖:

  • 表单绑定(Form Binding)
  • 后端验证(Validation)
  • 错误提示展示
  • 使用 @ValidBindingResult 处理验证失败
  • 国际化错误信息支持

并为每个小节提供完整的 HTML 页面 + Spring Boot 后端 Java 示例代码,帮助你掌握 Thymeleaf 在真实项目中的高级用法。


📌 一、表单绑定基础:使用 th:objectth:field

1.1 定义模型类(User)

// User.java
public class User {private String name;private String email;private Integer age;// Getter & Setter
}

1.2 HTML 表单绑定(form.html)

<!-- templates/form.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户注册</title>
</head>
<body><h2>注册用户</h2><form th:action="@{/submit}" th:object="${user}" method="post"><label>姓名:<input type="text" th:field="*{name}" /></label><br><br><label>邮箱:<input type="email" th:field="*{email}" /></label><br><br><label>年龄:<input type="number" th:field="*{age}" /></label><br><br><button type="submit">提交</button></form></body>
</html>

1.3 控制器接收数据(UserController.java)

@Controller
public class UserController {@GetMapping("/register")public String showForm(Model model) {model.addAttribute("user", new User());return "form";}@PostMapping("/submit")public String submitForm(@ModelAttribute("user") User user) {System.out.println("接收到的用户:" + user);return "redirect:/success";}
}

📌 输出效果:

  • 页面加载时显示空表单。
  • 提交后,控制台输出类似:
接收到的用户:User{name='张三', email='zhangsan@example.com', age=25}

📌 二、表单验证:使用 Bean Validation 注解

2.1 修改模型类添加验证规则(User.java)

import javax.validation.constraints.*;public class User {@NotBlank(message = "姓名不能为空")private String name;@Email(message = "请输入有效的邮箱地址")private String email;@Min(value = 0, message = "年龄不能小于0")@Max(value = 120, message = "年龄不能超过120")private Integer age;// Getter & Setter
}

2.2 控制器中使用 @Valid 验证

@PostMapping("/submit")
public String submitForm(@Valid @ModelAttribute("user") User user,BindingResult result,Model model) {if (result.hasErrors()) {return "form"; // 返回表单页面,显示错误}// 正常处理逻辑return "redirect:/success";
}

📌 三、在 Thymeleaf 中显示验证错误信息

3.1 修改 form.html 显示字段错误信息

<form th:action="@{/submit}" th:object="${user}" method="post"><label>姓名:<input type="text" th:field="*{name}" /><span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" style="color:red"></span></label><br><br><label>邮箱:<input type="email" th:field="*{email}" /><span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" style="color:red"></span></label><br><br><label>年龄:<input type="number" th:field="*{age}" /><span th:if="${#fields.hasErrors('age')}" th:errors="*{age}" style="color:red"></span></label><br><br><button type="submit">提交</button></form>

📌 效果说明:

  • 若未填写姓名,会显示红色错误提示:“姓名不能为空”
  • 邮箱格式错误,提示“请输入有效的邮箱地址”
  • 年龄不在 0~120 范围内,提示“年龄不能小于0”或“年龄不能超过120”

📌 四、全局错误信息与非字段错误

4.1 添加自定义业务验证逻辑

@PostMapping("/submit")
public String submitForm(@Valid @ModelAttribute("user") User user,BindingResult result,Model model) {if (user.getEmail().contains("blocked")) {result.rejectValue("email", "error.email", "该邮箱被禁止注册");}if (result.hasErrors()) {return "form";}return "redirect:/success";
}

4.2 显示全局错误信息

<div th:if="${#fields.hasGlobalErrors()}"><p style="color:red" th:each="error : ${#fields.globalErrors}" th:text="${error}"></p>
</div>

📌 示例输出:

该邮箱被禁止注册

📌 五、国际化错误信息支持(i18n)

5.1 创建消息属性文件

src/main/resources/messages.properties
src/main/resources/messages_zh_CN.properties

示例内容(messages_zh_CN.properties):

NotBlank.user.name=姓名不能为空
Email.user.email=请输入有效的邮箱地址
Min.user.age=年龄不能小于0
Max.user.age=年龄不能超过120
error.email=该邮箱被禁止注册

5.2 Thymeleaf 自动识别国际化信息

无需额外配置,Thymeleaf 会根据浏览器语言自动选择对应的消息文件。


✅ 总结

功能属性/注解用途
表单绑定th:object, th:field绑定模型对象到表单字段
数据验证@NotBlank, @Email, @Min, @Max校验字段合法性
验证结果@Valid, BindingResult接收验证结果并处理
错误提示th:errors, th:if显示字段错误信息
全局错误rejectValue, globalErrors处理非字段级错误
国际化messages_*.properties支持多语言错误提示

📚 推荐阅读

  • Thymeleaf 官方文档 - Form Handling
  • Spring Boot 表单验证最佳实践
  • Spring Validation 详解
http://www.dtcms.com/a/283812.html

相关文章:

  • Rabbitmq direct 模式与 finout区别
  • Apache Ignite 的 Pages Writes Throttling(页面写入节流)
  • C++ - 仿 RabbitMQ 实现消息队列--C++11 异步操作实现线程池
  • InfluxDB 3与Apache Parquet:打造高性能时序数据存储与分析解决方案
  • Apache DolphinScheduler介绍与部署
  • UE5 Nanite使用
  • 下班倒计时
  • 链路聚合实训
  • 管家婆价格折扣跟踪管理:查询、新增、修改、删除
  • JAVA中的Map集合
  • 【01背包】P1466 [USACO2.2] 集合 Subset Sums
  • 华为云容器产品分析
  • HTML表格基础
  • 【Linux】第一个小程序—进度条
  • HikariCP数据库连接池高性能优化实战指南
  • Spring Boot 参数校验:@Valid 与 @Validated
  • 线上协同办公时代:以开源AI大模型等工具培养网感,拥抱职业变革
  • 【前沿技术动态】【AI总结】Spring Boot 4.0 预览版深度解析:云原生时代的新里程碑
  • Fair-code介绍(Fair code)(一套新型软件模型:旨在“开源”“商业可持续性”中找到平衡)
  • Spring Boot Jackson 序列化常用配置详解
  • redis速记
  • Jenkins Git Parameter 分支不显示前缀origin/或repo/
  • 【37】MFC入门到精通——MFC中 CString 数字字符串 转 WORD ( CString, WORD/int 互转)
  • 我爱学算法之—— 前缀和(下)
  • 破局 Meme 币永续:跨界融合 Ormer + AI + 舆情监控 的颠覆性框架
  • 日志采集——ZeroMQ的配置
  • MyBatis 之配置与映射核心要点解析
  • 林曦词典|文质彬彬
  • 如何查询pg账号权限 能否创建模式 删表建表
  • Vim多列打开不同文件操作指南