初级MVC中参数强校验的核心是嵌入请求生命周期:①@Valid+BindingResult实现轻量入口校验;②@ExceptionHandler统一处理MethodArgumentNotValidException;③HandlerInterceptor前置卡点;④自定义注解+AOP实现可插拔校验。

在初级 MVC 脚手架(如 Spring Boot + Spring MVC)中,用流程控制实现参数合法性强校验,核心不是写一堆 if-else,而是把校验逻辑嵌入到请求处理的标准生命周期里——让校验成为“必经之路”,失败即中断,成功才进业务。关键在于分层拦截、按需触发、统一出口。
在 Controller 入口处用 @Valid + BindingResult 控制校验分支
这是最直接、最轻量的流程控制方式:校验动作由框架自动触发,开发者只负责定义“校验失败后做什么”。
- 在接收参数的 POJO 字段上标注 @NotBlank、@Min、@Email 等 JSR-303 注解,规则与模型绑定,清晰可读
- Controller 方法参数前加 @Valid,表示“此处必须校验”,不加则跳过
- 紧跟其后的 BindingResult result 必须紧邻 @Valid 参数,否则框架无法注入错误结果
- 手动判断 if (result.hasErrors()),走自定义错误响应(如返回统一 JSON 结构),否则继续执行业务逻辑
用 @RestControllerAdvice 统一拦截校验失败流程
避免每个接口都写重复的 if 判断,把“校验失败怎么返回”抽成全局流程。
- 定义一个带 @RestControllerAdvice 的类,专门捕获 MethodArgumentNotValidException
- 在对应 @ExceptionHandler 方法中,从异常里提取 BindingResult,组装标准错误体(如 code=400, message=“用户名不能为空”)
- 这样所有带 @Valid 的接口,一旦校验失败,自动走这里,Controller 方法体里就不用再写 if 判断了
- 配合 @ResponseStatus(HttpStatus.BAD_REQUEST) 可直接设定 HTTP 状态码
用 HandlerInterceptor 在进入 Controller 前做前置流程卡点
适合对某些路径做更早、更轻量的准入控制,比如检查必要 query 参数是否存在、时间戳是否过期等。
- 继承 HandlerInterceptor,重写 preHandle 方法
- 从 HttpServletRequest 中解析出关键参数(如 token、sign、timestamp),做基础合法性判断
- 不满足条件时直接 response.setStatus(400) 并 write 错误信息,然后 return false 阻断后续流程
- 只对 /api/** 等业务路径注册该拦截器,静态资源、健康检查等路径排除,避免干扰
用自定义注解 + AOP 实现可插拔的校验流程
当某类接口需要统一附加校验(如所有用户修改接口必须校验旧密码),又不想侵入每个 Controller 方法时,可用流程化扩展。
- 定义一个 @NeedOldPassword 注解,标注在 Controller 方法上
- 写一个 @Aspect 切面,在方法执行前读取该注解,解析请求体中的 oldPassword 字段
- 调用服务层验证逻辑,失败则抛出特定异常(如 InvalidOldPasswordException)
- 再用 @RestControllerAdvice 捕获该异常,统一转为错误响应


















