java自定义校验注解需用@constraint标记并指定validatedby,配合constraintvalidator实现;注解须声明@retention(runtime)和@target({field, parameter}),支持默认消息与分组。

Java 中自定义校验注解的核心是结合 javax.validation(或 jakarta.validation)的约束机制,通过定义注解 + 约束校验器(ConstraintValidator)来实现参数合法性检查。关键在于注解要声明约束逻辑,而校验器负责具体执行判断。
定义自定义校验注解
注解需用 @Constraint 标记,并指定对应的校验器类。它通常支持运行时保留(@Retention(RetentionPolicy.RUNTIME))、作用于字段/方法参数(@Target({FIELD, PARAMETER})),并提供默认错误消息和分组支持。
例如,校验手机号是否符合国内 11 位规则:
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface PhoneNumber {
String message() default "手机号格式不正确";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
}
实现 ConstraintValidator 接口
校验器类需实现 ConstraintValidator<phonenumber string></phonenumber>,泛型分别对应注解类型和被校验的数据类型。重写 isValid() 方法,在其中编写具体的合法性判断逻辑。
注意:校验器必须有无参构造函数,且不能依赖 Spring Bean 注入(除非显式配置为 Spring 管理的 validator 实例);若需注入服务(如查库去重),应通过 ConstraintValidatorContext 或借助 Spring 的 SpringConstraintValidatorFactory。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
示例实现:
public class PhoneNumberValidator implements ConstraintValidator<phonenumber string> {
private static final String REGEX = "^1[3-9]\d{9}$";
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null || value.trim().isEmpty()) {
return true; // 允许空值,由 @NotBlank 控制
}
return value.matches(REGEX);
}
}</phonenumber>
在 Controller 或 DTO 中使用
将注解加在需要校验的字段或方法参数上,并确保启用校验(如 Spring MVC 中开启 @Valid 或 @Validated)。
- 用于 DTO 字段:
@PhoneNumber private String phone; - 用于接口参数:
public ResponseEntity> register(@Valid @RequestBody UserDTO dto) - 校验失败时,Spring 会自动返回
MethodArgumentNotValidException,可统一捕获并转为友好提示
进阶:支持多语言与动态消息
若需根据上下文动态生成错误信息(如包含字段名、当前值),可在 isValid() 中调用 context.disableDefaultConstraintViolation(),再用 buildConstraintViolationWithTemplate() 自定义提示。
国际化支持则需将 message() 指向资源文件键(如 message = "{validation.phone.number}"),并在 ValidationMessages.properties 中配置对应文本。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










