Skip to content

数据校验 (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 现在原生支持这种校验,且性能更高、错误信息处理更标准。

Based on Spring Framework.