通过实现ConstraintValidator完成自定义校验注解

首先贴上代码

@Data
public class LoginVO {
    @NotNull
    @IsMobile
    private String mobile;

    @NotNull
    @Length(min = 32)
    private String password;

}
public class IsMobileValidator implements ConstraintValidator<IsMobile,String> {

    private boolean require = false;

    @Override
    public void initialize(IsMobile constraintAnnotation) {
        require = constraintAnnotation.required();
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        if(require){
            return ValidatorUtils.isMobile(s);
        }else {
           if (StringUtils.isEmpty(s)) {
               return true;
           }else {
               return ValidatorUtils.isMobile(s);
           }
        }
    }
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {IsMobileValidator.class}
)
public @interface IsMobile {

    boolean required() default true;

    String message() default "手机号格式不正确";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};


}
public class ValidatorUtils {

    private static final Pattern mobile_pattern = Pattern.compile("1\\d{10}");

    public static boolean isMobile(String src) {
        if (StringUtils.isEmpty(src)) {
            return false;
        }
        Matcher m = mobile_pattern.matcher(src);
        return m.matches();
    }
}
1. LoginVO类为一个普通的实体类其中的mobile属性添加了自定义注解
2. IsMobile类为自定义的字段注解未了解过注解的同学请自行百度在此不做基础介绍该自定义注解类中用到了四种元注解最后一个@Constraint指定了校验类也就是接下来的IsMobileValidator类值得一提的是除了自定义的messagerequire属性外下面的groups和payload也是必须添加的
3. ValidatorUtils为一个工具类简单校验了是否为手机号没有了解过的可以看我之前的一篇博文https://blog.csdn.net/qq_38439885/article/details/80230753
4. IsMobileValidator为自定义注解的校验类
校验类需要实现ConstraintValidator接口
接口使用了泛型需要指定两个参数第一个自定义注解类第二个为需要校验的数据类型
实现接口后要override两个方法分别为initialize方法和isValid方法其中initialize为初始化方法可以在里面做一些初始化操作isValid方法就是我们最终需要的校验方法了可以在该方法中实现具体的校验步骤本示例中进行了简单的手机号校验

完成这几部分之后一个简单的自定义校验注解就完成啦不要忘记在使用的时候加上@Valid注解开启valid校验

那么如何获取在注解中定义的message信息呢

在valid校验中如果校验不通过会产生BindException异常捕捉到异常后可以获取到defaultMessage也就是自定义注解中定义的内容具体实现如下
```java
    BindException ex = (BindException)e;
    List<ObjectError> errors = ex.getAllErrors();
    ObjectError error = errors.get(0);
    String msg = error.getDefaultMessage();