@Validated用于方法参数校验需类加@Validated注解且类由Spring管理;普通参数如String须封装DTO或用自定义注解,直接标注@NotBlank无效。

在 Java 中,@Validated 可以用于方法参数级别校验普通参数(如 String、Integer、自定义对象等),但需要满足两个前提:方法所在类被 Spring 管理(如加了 @Service 或 @RestController),且该类启用了方法级验证(Spring 默认不自动开启,需显式配置或使用特定注解)。
启用方法级参数校验
Spring Boot 2.3+ 默认已引入 spring-boot-starter-validation,无需额外引入依赖。但要让 @Validated 在方法上生效,必须确保目标类被 @Validated 注解标记(类级别),或使用 @Valid 配合嵌套校验场景 —— 而方法级普通参数校验,类上必须加 @Validated。
- 不加
@Validated在类上,方法参数上的@Validated或@NotBlank等注解会被完全忽略 -
@Validated类注解会触发 Spring AOP 代理,拦截方法调用并执行参数校验逻辑 - 若类是 final 的、方法是 private / static / final,代理可能失效,校验不触发
校验普通参数(如 String、int 等)
基本类型和包装类、字符串等不能直接加 @NotBlank 等约束注解——因为它们不是 Bean,无法承载 JSR-303 注解。正确做法是:将参数封装进一个带校验注解的 参数对象(DTO),或使用 分组校验 + @Validated 接口 控制校验时机。
但 Spring 支持对“方法参数本身”做校验,前提是:参数类型是 支持约束注解的类型(即该类型自身声明了 @Constraint 注解,比如自定义注解),或使用 @Valid 标记其内部字段(仅适用于对象)。对于纯 String 参数,标准方案是:
立即学习“Java免费学习笔记(深入)”;
- 定义一个带校验规则的 DTO,把普通参数作为字段放入其中(推荐,清晰可控)
- 或使用
@Validated+ 自定义约束注解(如@ValidPhone)作用于参数,再配合 ConstraintValidator 实现校验逻辑 - 不建议直接在
String name上写@NotBlank—— 编译通过,但运行时无效(无效果)
正确示例:DTO 封装 + 方法级 @Validated
这是最常用、最可靠的方式:
@Service
@Validated // ⚠️ 必须加在类上!
public class UserService {
public void createUser(@Valid @NotNull CreateUserDTO dto) {
// 业务逻辑
}
}
public class CreateUserDTO {
@NotBlank(message = "用户名不能为空")
private String username;
@Min(value = 18, message = "年龄不能小于18")
private Integer age;
// getter/setter...
}
注意:@Valid 用于触发 DTO 内部字段校验;@Validated 类注解使整个机制生效;如果想按场景分组,可定义接口(如 CreateGroup),并在 DTO 字段上标注 @NotBlank(groups = CreateGroup.class),方法参数写成 @Validated(CreateGroup.class) CreateUserDTO dto。
校验单个字符串参数(进阶:自定义注解)
若坚持校验裸参(如 String phone),需自定义约束注解:
@Target({METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhone {
String message() default "手机号格式错误";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.trim().isEmpty()) return true; // 允许空,由 @NotBlank 单独控
return value.matches("1[3-9]\d{9}");
}
}
// 使用方式
public void bindPhone(@ValidPhone String phone) { ... }
此时 @ValidPhone 是作用于参数的约束注解,配合类上 @Validated,Spring 会识别并校验该参数值。
不复杂但容易忽略:类加 @Validated、参数用 @Valid(对象)或自定义注解(基础类型)、避免在基础类型上误用 @NotBlank。


















