How to write custom annotations?

Custom check

  •  1)、编写一个自定义的校验注解
    
  •  2)、编写一个自定义的校验器 ConstraintValidator
    
  •  3)、关联自定义的校验器和自定义的校验注解
    

How to write validation annotations, we can refer to @NotBlank in JSR303:
Insert picture description here
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
Insert picture description here
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:
Insert picture description here
Insert picture description here
that is, we need to specify an array of type ConstraintValidator, and then, we are looking at the implementation of ConstraintValidator,
Insert picture description here
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.
Insert picture description here
When we submit a request with postMan:
Insert picture description here
showStatus is the same as the information in the ValidationMessages.properties we wrote. Of course, we can also change the prompt information through Messenge.

Guess you like

Origin blog.csdn.net/lq1759336950/article/details/113776973