spring mvc 结合 jsr-303 通过 @valid 实现服务端自动表单校验,核心是声明约束(如 @notblank)、触发校验(@valid + bindingresult)及处理结果;需引入 validation-api 和 hibernate-validator,配置 ,并确保 bindingresult 紧跟被校验对象。

校验前需准备基础依赖和配置
确保项目中包含 JSR-303 规范接口与 Hibernate Validator 实现:
-
validation-api(JSR-303 接口定义,如@NotNull等注解本身) -
hibernate-validator(官方参考实现,提供具体校验逻辑)
Spring MVC 需启用校验支持:在 spring-mvc.xml 中添加
<annotation-driven></annotation-driven>
该标签会自动注册 LocalValidatorFactoryBean,无需手动配置 validator bean(除非需自定义消息源或方言)。
在实体类上标注 JSR-303 约束注解
校验目标是 Java Bean 字段,常见注解包括:
-
@NotNull:非 null(但允许空字符串) -
@NotBlank:非 null 且 trim 后长度 > 0(专用于 String) -
@Email:格式符合邮箱基本规范 -
@Size(min=1, max=20):适用于 String、Collection、Array 等 -
@Min(18) / @Max(120):适用于数值类型 -
@Pattern(regexp = "^[a-zA-Z0-9_]+$"):正则匹配
示例:
@Data
public class User {
@NotBlank(message = "用户名不能为空")
private String userName;
@Min(0) @Max(150)
private Integer age;
@Email(message = "邮箱格式不合法")
private String email;
}
Controller 方法中正确使用 @Valid 和 BindingResult
关键规则:`@Valid` 注解的参数后必须紧接一个 `BindingResult` 类型参数,否则校验失败时 Spring 会直接抛出 MethodArgumentNotValidException(导致 400 错误)。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
正确写法:
@PostMapping("/register")
public String register(@Valid User user, BindingResult result, Model model) {
if (result.hasErrors()) {
// 获取所有错误信息,例如:result.getFieldError("email").getDefaultMessage()
model.addAttribute("errors", result.getAllErrors());
return "register"; // 返回表单页,展示错误
}
userService.save(user);
return "redirect:/success";
}
注意:BindingResult 必须紧跟在被校验对象之后,中间不能插入其他参数。
前端配合展示校验结果(可选但推荐)
使用 Spring 的表单标签库可简化错误渲染:
<form modelattribute="user" method="post">
<errors path="*" cssclass="alert alert-danger"></errors><div>
<label>用户名:</label>
<input path="userName"><errors path="userName" cssclass="text-danger"></errors>
</div>
<div>
<label>邮箱:</label>
<input path="email"><errors path="email" cssclass="text-danger"></errors>
</div>
<button type="submit">提交</button>
</form>
其中 path="*" 显示全局错误,path="fieldName" 显示字段级错误。
进阶:嵌套对象与分组校验
若实体含关联对象(如 User 包含 Address address),需在嵌套字段上加 @Valid 才能递归校验:
public class User {
@Valid // 触发 Address 内部校验
private Address address;
}
如需不同场景不同规则(如新增 vs 修改),可用校验分组:
- 定义分组接口:
public interface Update {} - 字段指定分组:
@NotBlank(groups = Update.class) - Controller 中使用:
@Validated(Update.class) User user
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










