spring boot 参数校验失败默认返回400,但应自定义为422;需通过@restcontrolleradvice捕获methodargumentnotvalidexception或bindexception,并用@responsestatus(httpstatus.unprocessable_entity)或responseentity设置状态码,同时在响应体中返回业务码如{"code":1002,"message":"参数校验失败"}。

Spring Boot 中参数校验失败默认返回 HTTP 400(Bad Request),但这个状态码可以按需自定义,关键在于**异常类型识别 + 全局异常处理器配置**,而不是修改注解本身。
明确校验失败触发的异常类型
不同参数绑定方式会抛出不同异常,需分别处理:
-
@RequestBody + @Valid/@Validated → 抛出
MethodArgumentNotValidException -
@RequestParam/@ModelAttribute + @Valid → 抛出
BindException - 手动调用 Validator.validate() → 不抛异常,需自行判断并 throw 自定义异常
在全局异常处理器中指定状态码
使用 @RestControllerAdvice 拦截对应异常,并通过 @ResponseStatus 注解或 ResponseEntity 显式设置 HTTP 状态码:
- 直接加
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)(推荐 422):语义更准确,表示请求格式正确但语义无效 - 用
ResponseEntity.status(422).body(...):灵活性更高,可动态决定状态码 - 避免硬写
400,除非业务规范强制要求;422 是 RESTful API 更通用的选择
统一响应体中携带业务状态码(非 HTTP 状态码)
HTTP 状态码用于通信层语义,而业务错误码(如 1002)应放在 JSON 响应体中,与前端约定清晰:
- 响应结构示例:
{"code":1002,"message":"参数校验失败","data":null} - 业务码建议用枚举管理(如
PARAM_VALID_ERROR(1002, "参数校验失败")),避免散落字符串 - HTTP 状态码和业务码可不一致——例如 HTTP 返回 200 + 业务码 1002,适合部分前端框架对非 200 状态处理不友好场景
注意校验注解生效的前提条件
状态码能被正确捕获,前提是校验确实触发了异常:
- Controller 方法参数必须加
@Valid或@Validated,且对象字段有 JSR-303 注解(如@NotBlank) - 不要同时在方法参数后声明
BindingResult,否则 Spring 不会抛异常,而是静默填充结果 - 确保全局异常处理器类被 Spring 扫描到(加
@RestControllerAdvice,且包路径在 component-scan 范围内)











