校验核心是注解用法、对象校验和错误统一处理:@NotNull/@NotBlank/@NotEmpty等需按类型选用;@RequestBody用@Valid,单字段用@Validated;嵌套对象须逐层加@Valid;异常须用@ControllerAdvice统一捕获MethodArgumentNotValidException和ConstraintViolationException。

直接抓住三个主干:注解怎么用、对象怎么校、错误怎么统。其他都是在这基础上的延伸。
注解用法要分清适用场景
@NotNull 适用于所有类型,但不拦空字符串;@NotBlank 专治 String,会过滤纯空格;@NotEmpty 用于集合、Map、数组,要求非 null 且 size > 0;@Min/@Max 只对数值型有效;@Size 控制字符串长度或集合大小;@Pattern 和 @Email 必须配合正则或格式规则使用,注意 message 提示要明确。
常见混淆点:
- 路径变量(@PathVariable)和查询参数(@RequestParam)需在 Controller 类上加 @Validated 才能触发单字段校验
- @RequestBody 对象必须用 @Valid(不是 @Validated)启动嵌套校验
- 同一字段多个注解可共存,校验按声明顺序执行,失败即停
复杂对象校验要层层带 @Valid
DTO 中含 List 或子对象时,仅在字段上加 @Valid 才能穿透校验。比如订单含商品列表,需这样写:
@Valid private List items;
子类 OrderItemDTO 内部字段同样需标注 @NotBlank、@Min 等。没有 @Valid,校验就卡在 list 层,不会进到每个 item 里。
嵌套层级深也没关系,只要每层需要校验的引用字段都标了 @Valid,框架自动递归处理。
错误响应必须统一拦截处理
校验失败默认抛出 MethodArgumentNotValidException(@RequestBody)或 ConstraintViolationException(@Validated 单参数),不能让异常直接透出。
推荐做法是写一个 @ControllerAdvice 全局异常处理器,捕获这两类异常,提取字段名和 message,组装成标准 JSON 返回,例如:
{ "code": 400, "message": "请求参数错误", "details": [ { "field": "phone", "message": "手机号格式不正确" } ] }
注意:不要只 catch Exception,否则会漏掉校验异常;也不要手动 try-catch 每个接口,破坏统一性。


















