spring boot接口参数校验三步走:加spring-boot-starter-validation依赖;在dto字段用@notblank、@email等注解声明规则;controller参数加@valid触发校验,再用@restcontrolleradvice统一处理异常返回结构化错误。

直接上手做,核心就三件事:加依赖、写校验规则、统一处理错误。不绕弯子,也不堆概念。
第一步:引入校验能力
Spring Boot 2.3+ 版本起,spring-boot-starter-validation 不再自动包含在 web starter 里,必须显式添加:
- 在
pom.xml中加入:
加完就能用 @NotBlank、@Min、@Email 这些注解了,无需额外配置。
第二步:DTO 里写清楚要校什么
别在校验逻辑里写 if-else,把规则“贴”在字段上。比如用户注册 DTO:
-
@NotBlank(message = "用户名不能为空")—— 字符串非空且去空格后长度 > 0 -
@Email(message = "邮箱格式不正确")—— 自动校验邮箱结构 -
@Pattern(regexp = "^1[3-9]\d{9}$", message = "手机号格式错误")—— 自定义正则 -
@Min(value = 18, message = "年龄不能小于18岁")—— 数值范围控制
注意:@NotNull 允许空字符串,@NotEmpty 拒绝空集合/空字符串,选错容易踩坑。
第三步:Controller 层触发校验
在接口参数上加 @Valid 或 @Validated:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
@RequestBody @Valid UserRegisterDTO dto—— 用于 JSON 请求体 -
@PathVariable @Min(1) Long id—— 路径变量也能校 -
@RequestParam @NotBlank String name—— 查询参数同样支持
校验失败时,Spring 会自动抛出 MethodArgumentNotValidException(请求体)或 ConstraintViolationException(路径/查询参数),不用手动 catch。
第四步:全局拦截错误,返回统一格式
建一个异常处理器类,用 @RestControllerAdvice 拦住所有校验异常:
- 捕获
MethodArgumentNotValidException,提取每个字段的错误信息,组装成{"code":400,"msg":"用户名不能为空","details":[{"field":"username","reason":"不能为空"}]} - 捕获
ConstraintViolationException,处理@PathVariable和@RequestParam的报错 - 顺便把
NullPointerException、IllegalArgumentException等也兜底一下,避免 500 泄露堆栈
这样前端收到的永远是结构清晰的错误响应,不需要每个接口自己写 BindingResult 判断。
进阶可选:分组校验和自定义注解
如果新增和修改共用一个 DTO,但校验规则不同(比如新增时 id 为空,修改时 id 必填),就用分组:
- 定义两个空接口:
interface Create {}和interface Update {} - 字段上标注:
@Null(groups = Create.class)、@NotNull(groups = Update.class) - Controller 方法写:
@Validated(Create.class) @RequestBody UserDTO dto
需要校验身份证号、银行卡号等复杂规则?写个自定义注解,实现 ConstraintValidator 接口,复用性比写一堆 if 强得多。










