Custom check
-
1)、编写一个自定义的校验注解
-
2)、编写一个自定义的校验器 ConstraintValidator
-
3)、关联自定义的校验器和自定义的校验注解
How to write validation annotations, we can refer to @NotBlank in JSR303:
He has three attributes:
//校验出错后,去此路径下去拿去错误信息,
String message() default "{javax.validation.constraints.NotBlank.message}";
//支持分组检验功能
Class<?>[] groups() default {
};
//负载信息
Class<? extends Payload>[] payload() default {
};
Therefore, we first need to copy these three pieces of information (we name our own verification class ListValue
):
Of course, we also need to copy these 5 notes.
@Documented
//该校验注解使用那个校验器进行校验
@Constraint(validatedBy = {
})
//此注解可以标注在哪些位置
@Target({
METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
//校验注解的时机
@Retention(RUNTIME)
//可重复注解可不要
@Repeatable(List.class)
But these annotations are in the javax.validation package, so they must be introduced in maven first:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
3. Because JSR303 obtains the error information in the ValidationMessages.properties file by default, if we modify the path, we must create a new ValidationMessages.properties file by
ourselves. For example, my ListValue is written!
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 {
};
}
Next, we need to specify which validator to use to validate the annotation. Same as above, we can look at the implementation of validatedBy:
that is, we need to specify an array of type ConstraintValidator, and then, we are looking at the implementation of ConstraintValidator,
you can see that it is an excuse ConstraintValidator <A extends Annotation, T>, first specify the generic annotation, second generic designated check what type of data , so we only need to write a check to implement this method is the interface can be!
less Is my validator:
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);
}
}
At this point, my ListValue can be used normally.
When we submit a request with postMan:
showStatus is the same as the information in the ValidationMessages.properties we wrote. Of course, we can also change the prompt information through Messenge.