Spring Boot参数校验关键在触发时机、作用位置和错误处理:@Valid需配BindingResult且支持嵌套校验,@Validated支持分组但不自动嵌套;集合类型须封装包装类;@ConfigurationProperties需加@Validated;3.x用jakarta包;需全局异常处理器统一返回可读错误。

Spring Boot 参数校验不是加几个注解就完事的事,关键在“触发时机”“作用位置”和“错误处理”这三个地方。很多团队线上出问题,不是没写校验,而是校验写了但根本没跑起来。
校验注解必须配对使用才生效
@Valid 和 @Validated 看似相似,但行为差异很大:
- @Valid 是 Java 标准(JSR-303/380),支持嵌套校验,但不能单独用在方法参数上触发全局校验;必须配合 BindingResult 才能捕获错误,否则校验失败静默吞掉
- @Validated 是 Spring 扩展,支持分组校验、类级别启用,但不支持自动嵌套校验——想校验 UserDTO 里的 AddressDTO,AddressDTO 字段上还得显式加 @Valid
- Controller 方法参数用 @Valid 时,必须紧跟一个 BindingResult 参数,顺序不能错;用 @Validated 则可省略 BindingResult,但需配合全局异常处理器捕获 MethodArgumentNotValidException
列表和 Map 类型不能直接加 @Valid
下面这种写法是无效的:
public Result save(@RequestBody @Valid List
原因:Spring 的参数解析器不支持对裸集合类型做递归校验。正确做法是封装成包装类:
- 新建一个 Request 类,如 OrderBatchRequest,内部持有一个 @Valid List
字段 - 在 Controller 中对这个 Request 对象加 @Valid,校验逻辑就能正常进入 BindingValidator
- 如果用的是 @RequestBody + JSON 数组,前端传过来的是数组结构,后端必须通过包装类承接,否则校验器压根不启动
配置类校验容易被忽略
@ConfigurationProperties 绑定的配置项,比如数据库连接、第三方密钥,同样需要校验。很多人只校验接口参数,却放任非法配置启动成功:
- 配置类必须加 @Validated 注解,字段上加 @NotBlank、@Min 等约束
- Spring Boot 3.x 默认启用启动时校验(fail-fast),若配置不合法,应用直接启动失败,并打印明确错误位置
- 注意包路径:Spring Boot 2.x 用 javax.validation.constraints,3.x 起全部迁移到 jakarta.validation.constraints,混用会导致注解失效
错误提示要统一且可读
默认的校验异常返回的是英文字段名和模糊信息,前端无法友好展示:
- 定义全局异常处理器,捕获 MethodArgumentNotValidException,提取 FieldError 中的 field、rejectedValue、defaultMessage
- 把 message 中的占位符(如 {min})替换成真实值,或对接 i18n 实现多语言提示
- 避免直接返回 Hibernate Validator 的原始堆栈,也不要把 BindingResult.toString() 当响应体返回


















