先导
在使用JSR303-后端校验时给定的校验注解不满足使用场景且成员变量类型不支持使用正则校验(正则校验仅支持字符串类型的成员变量的校验)时可以使用自定义校验注解解决问题。
自定义注解的基本创建步骤
1.编写一个自定义校验注解
/**
* 自定义校验注解-只允许输入注解传递的值
* 必须填写三个属性
* message() 出错后错误信息寻找
* groups() 支持分组校验
* payload() 自定义一些负载信息
* 且要标记如下注解
* @Constraint指定校验器 这里需要创建一个ListValConstraintValidator
* @Target注解可以标识的位置
* @Retention校验注解可以在运行时获取
*
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { })
public @interface ListValue {
//默认错误信息默认为 ValidationMessages.properties 中的 com.atguigu.common.validator.ListValue.message值
//在resoureces下创建一个ValidationMessages.properties并给com.atguigu.common.validator.ListValue.message赋值
String message() default "{com.atguigu.common.validator.ListValue.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
//指定传入值
int[] vals() default {};
}
2.指定错误信息引用或新增ValidationMessages.properties文件并赋值
3.编写自定义校验器ConstraintValidator
/**
* 自定义注解ListVal的校验器
* 实现ConstraintValidator<A,T>
* A传入校验的注解 T传入可以标记的类型
* 并实现两个方法
*/
public class ListValConstraintValidator implements ConstraintValidator<ListValue,Integer> {
//自定一个Set集合
private Set<Integer> set = new HashSet<>();
//初始化方法
@Override
public void initialize(ListValue constraintAnnotation) {
//获取详细信息 从ListValue定义的vals()方法获取指定值
int[] vals = constraintAnnotation.vals();
//遍历vals 并添加到set中
for (int val : vals) {
set.add(val);
}
}
//判断是否校验成功
//其中value是注解获取到的需要校验的值
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
//判断依据 如果set中不包含带校验值value返回false否则true
return set.contains(value);
}
}
4.关联自定义注解和自定义校验器
在自定义注解类中指定注解@Constraint的validatedBy值
//指定校验器 与自定义校验器产生关联
@Constraint(validatedBy = { ListValConstraintValidator.class })