自定义校验
-
1)、编写一个自定义的校验注解
-
2)、编写一个自定义的校验器 ConstraintValidator
-
3)、关联自定义的校验器和自定义的校验注解
如何编写校验注解,我们可以参考JSR303中的@NotBlank:
他拥有三个属性:
//校验出错后,去此路径下去拿去错误信息,
String message() default "{javax.validation.constraints.NotBlank.message}";
//支持分组检验功能
Class<?>[] groups() default {
};
//负载信息
Class<? extends Payload>[] payload() default {
};
故,我们首先要将这三个信息复制过来(我们给自己的校验类起名ListValue
):
当然也要将它的这5个注解复制过来
@Documented
//该校验注解使用那个校验器进行校验
@Constraint(validatedBy = {
})
//此注解可以标注在哪些位置
@Target({
METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
//校验注解的时机
@Retention(RUNTIME)
//可重复注解可不要
@Repeatable(List.class)
但这些注解又是javax.validation包中的,因此要先在maven中引入:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
3.因为JSR303默认是在ValidationMessages.properties文件中获取错误信息,故如果我们修改路径要自己新建一个ValidationMessages.properties文件例如我的
ListValue即编写完成!
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented
@Constraint(validatedBy = {
ListValueConstraintValidator.class})
@Target({
METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.atguigu.common.valid.ListValue.message.message}";
Class<?>[] groups() default {
};
Class<? extends Payload>[] payload() default {
};
int[] vals() default {
};
}
接着要指定改注解用哪个校验器进行校验,同上,我们可以看一下validatedBy的实现:
即我们需要指定一个数组,类型为ConstraintValidator,然后,我们在看看ConstraintValidator的实现,
可以看到,它是一个借口ConstraintValidator<A extends Annotation, T>,第一个泛型指定注解,第二个泛型指定校验什么类型数据,因此我们编写的校验器只需要实现这个接口的方法即可!
以下是我的校验器:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
//拿到我们注解的Vals的值0,1,
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
//判断是否检验成功!
/**
*
* @param value 我们提交的值(需要校验的值
* @param context,上下文环境信息
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
此时,我的ListValue即可正常使用
当我们用postMan提交请求时:
showStatus即和我们编写的ValidationMessages.properties中的信息一致,当然我们也可以通过Messenge改变提示信息.