数据校验 (Validation)
Spring MVC 内置了对 Java Bean Validation (JSR-303/JSR-380) 的支持。校验通常发生在两个层面:
1. 对特定对象的校验
当你使用 @ModelAttribute、@RequestBody 或 @RequestPart 时,可以加上 @Valid (Jakarta 标准) 或 @Validated (Spring 特有) 注解。
java
@PostMapping("/user")
public void handle(@Valid @RequestBody User user) {
// 如果校验失败,默认抛出 MethodArgumentNotValidException (400)
}2. 对方法参数的校验 (Spring 6.1+)
从 Spring 6.1 开始,你可以直接在基本类型参数上使用约束注解。
java
@GetMapping("/search")
public List<User> search(@NotBlank @Size(min=2) @RequestParam String name) {
// 校验失败抛出 HandlerMethodValidationException
}异常处理对比
| 异常类型 | 适用场景 | 处理建议 |
|---|---|---|
| MethodArgumentNotValidException | 单个复杂对象的校验失败 | 针对 REST API 返回具体的字段错误列表。 |
| HandlerMethodValidationException | 多个参数或基本类型的校验失败 | 使用 Spring 6.1+ 的 visitResults 方法进行遍历处理。 |
补充教学
1. @Valid vs @Validated
- @Valid:标准 JSR 注解,支持嵌套校验(比如 User 里的 Address 也要校验)。
- @Validated:Spring 提供的,支持校验分组(例如:创建用户时需要选填密码,修改用户时密码可为空)。
2. 本地处理错误 (不抛异常)
如果你希望在 Controller 里自己处理错误而不让 Spring 直接返回 400,只需在参数后紧跟一个 BindingResult:
java
public String save(@Valid User user, BindingResult result) {
if (result.hasErrors()) {
return "userForm"; // 返回页面显示错误信息
}
return "redirect:/success";
}3. 注意 6.1+ 的重大变化
过去,要在 Controller 里校验基本参数(如 @Min(1) int id),你必须在类上加 @Validated,这会导致 Spring 使用 AOP 代理。 在 Spring 6.1+ 中:建议移除类级别的 @Validated。Spring MVC 现在原生支持这种校验,且性能更高、错误信息处理更标准。