欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot validation 自定义验证注解

程序员文章站 2022-07-10 21:07:25
springbootvalidation 自定义验证注解...

springboot validation 自定义验证注解

 

应用:自定义注解对pojo进行检验

 

 

************************

相关类与接口

 

ConstraintValidator:自定义注解对应验证规则

public interface ConstraintValidator<A extends Annotation, T> {
    default void initialize(A constraintAnnotation) {
    }

    boolean isValid(T var1, ConstraintValidatorContext var2);
}

第一个参数A表示验证注解,第二个参数T表示注解标注的对象

 

@Length

@Documented
@Constraint(
    validatedBy = {}
)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Length.List.class)
public @interface Length {
    int min() default 0;

    int max() default 2147483647;

    String message() default "{org.hibernate.validator.constraints.Length.message}";

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

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

    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface List {
        Length[] value();
    }
}

 

LengthValidator:长度验证器

public class LengthValidator implements ConstraintValidator<Length, CharSequence> {
    private static final Log LOG = LoggerFactory.make(MethodHandles.lookup());
    private int min;
    private int max;

    public LengthValidator() {
    }

    public void initialize(Length parameters) {
        this.min = parameters.min();
        this.max = parameters.max();
        this.validateParameters();
    }

    public boolean isValid(CharSequence value, ConstraintValidatorContext constraintValidatorContext) {
        if (value == null) {
            return true;
        } else {
            int length = value.length();
            return length >= this.min && length <= this.max;
        }
    }

    private void validateParameters() {
        if (this.min < 0) {
            throw LOG.getMinCannotBeNegativeException();
        } else if (this.max < 0) {
            throw LOG.getMaxCannotBeNegativeException();
        } else if (this.max < this.min) {
            throw LOG.getLengthCannotBeNegativeException();
        }
    }
}

 

 

************************

示例:定义类验证注解,检验price*amount、totalFee的差值

 

********************

validation 层

 

@CheckNum

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {CustomValidator.class})
@Target({ElementType.TYPE,ElementType.ANNOTATION_TYPE})
public @interface CheckNum {

    String field();
    String field2();
    String field3();

    String message() default "{org.hibernate.validator.constraints.Length.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

 

CustomValidator

public class CustomValidator implements ConstraintValidator<CheckNum, Object> {

    private String field;
    private String field2;
    private String field3;

    @Override
    public void initialize(CheckNum constraintAnnotation) {
        this.field=constraintAnnotation.field();
        this.field2=constraintAnnotation.field2();
        this.field3=constraintAnnotation.field3();
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        BeanWrapper beanWrapper=new BeanWrapperImpl(o);
        Double price=Double.parseDouble(Objects.requireNonNull(Objects.requireNonNull(beanWrapper.getPropertyValue(field)).toString()));
        Integer amount=Integer.parseInt(Objects.requireNonNull(Objects.requireNonNull(beanWrapper.getPropertyValue(field2)).toString()));
        double totalFee=Double.parseDouble(Objects.requireNonNull(Objects.requireNonNull(beanWrapper.getPropertyValue(field3)).toString()));

        return Math.abs(totalFee-price*amount)<0.01;
    }
}

 

********************

pojo 层

 

Order

@Data
@CheckNum(field = "price",field2 = "amount",field3 = "totalFee",message = "totalFee 与 price*amount数值相差超过0.01")
public class Order {

    private Double price;
    private Integer amount;
    private Double totalFee;
}

 

********************

controller 层

 

HelloController

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(@Validated Order order, BindingResult result){
        System.out.println(order);

        if (result.hasErrors()){
            result.getAllErrors().forEach(error -> {
                System.out.print("field:"+error.getObjectName());
                System.out.println(" ==> message:"+error.getDefaultMessage());
            });
        }

        return "success";
    }
}

 

 

************************

使用测试

 

localhost:8080/hello?price=2&amount=8&totalFee=8

2020-07-15 11:53:21.378  INFO 340 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-07-15 11:53:21.382  INFO 340 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
Order(price=2.0, amount=8, totalFee=8.0)
field:order ==> message:totalFee 与 price*amount数值相差超过0.01

 

 

本文地址:https://blog.csdn.net/weixin_43931625/article/details/107343789