1、validation的使用

1、配置一个注解用来只在几个值之间选择

1、创建注解EnumValue

  1. package com.asto.tax.common.validation.annotation;
  2. /**
  3. * @author djy
  4. * @createTime 2021/11/24 下午4:47
  5. * @description 用于检验传递的参数必须是在指定的值中,但是也可以通过require来指定 这个值可以为空的情况
  6. * * 使用案例
  7. * * @EnumValue(strValues = {"ALL", "REVIEWED", "PROCESSING", "WAIT_INVOICE", "INVOICED"},
  8. * * message = "如果传了值,必须是ALL,REVIEWED,PROCESSING,WAIT_INVOICE,INVOICED",require = false)
  9. * * private String invoiceStatus;
  10. */
  11. import com.asto.tax.common.validation.annotation.validator.EnumValueValidator;
  12. import javax.validation.Constraint;
  13. import javax.validation.Payload;
  14. import java.lang.annotation.Documented;
  15. import java.lang.annotation.Retention;
  16. import java.lang.annotation.Target;
  17. import static java.lang.annotation.ElementType.*;
  18. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  19. @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
  20. @Retention(RUNTIME)
  21. @Documented
  22. @Constraint(validatedBy = {EnumValueValidator.class})
  23. public @interface EnumValue {
  24. // 默认错误消息
  25. String message() default "必须为指定值";
  26. String[] strValues() default {};
  27. int[] intValues() default {};
  28. // 分组
  29. Class<?>[] groups() default {};
  30. /**
  31. * 是否是必须有值 默认是
  32. */
  33. boolean require() default true;
  34. // 负载
  35. Class<? extends Payload>[] payload() default {};
  36. // 指定多个时使用
  37. @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})
  38. @Retention(RUNTIME)
  39. @Documented
  40. @interface List {
  41. EnumValue[] value();
  42. }
  43. }

2、创建注解校验器EnumValueValidator

  • 主要是在方法isValid中进行判断 ```java package com.asto.tax.common.validation.annotation.validator;

import com.asto.tax.common.validation.annotation.EnumValue;

import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext;

/**

  • @author djy
  • @createTime 2021/11/24 下午4:49
  • @description */ public class EnumValueValidator implements ConstraintValidator { private String[] strValues; private int[] intValues; private boolean require;

    @Override public void initialize(EnumValue constraintAnnotation) {

    1. strValues = constraintAnnotation.strValues();
    2. intValues = constraintAnnotation.intValues();
    3. require = constraintAnnotation.require();

    }

    @Override public boolean isValid(Object value, ConstraintValidatorContext context) {

     if (value instanceof String) {
         for (String s : strValues) {
             if (s.equals(value)) {
                 return true;
             }
         }
         return false;
     } else if (value instanceof Integer) {
         for (int s : intValues) {
             if (s == ((Integer) value).intValue()) {
                 return true;
             }
         }
         return false;
     }
     return !this.require;
    

    } }

<a name="dLRPw"></a>
### 3、使用示例
```java
package com.asto.tax.supervise.pojo.dto;

import com.asto.tax.common.validation.annotation.EnumValue;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * @author djy
 * @createTime 2021/11/25 上午11:27
 * @description 用于交税管理-增值税列表查询
 */
@Data
@Accessors(chain = true)
public class OrderInvoiceAddTaxSearchDto extends SearchPageListDto implements Serializable {
    private static final long serialVersionUID = -5707180282202808724L;

    @EnumValue(strValues = {"ALL", "REVIEWED", "PROCESSING", "WAIT_INVOICE", "INVOICED"},
            message = "如果传了值,必须是ALL,REVIEWED,PROCESSING,WAIT_INVOICE,INVOICED", require = false)
    private String invoiceStatus;
}

4、总结

  • 可以达到如果是上面这些值就会通过校验。

2、自定义配置正则注解在字段是null和空字符串的时候都直接放行

  • 默认validation中@Pattern注解是只对值是null的时候是放行的。

    1、自定义创建一个注解@PatternNullable

    ```java /*

import com.asto.tax.common.validation.annotation.validator.PatternNullableValidator;

import javax.validation.Constraint; import javax.validation.Payload; import javax.validation.constraints.Pattern.List; import java.lang.annotation.Documented; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**

  • The annotated {@code CharSequence} must match the specified regular expression.
  • The regular expression follows the Java regular expression conventions
  • see {@link java.util.regex.Pattern}.
  • Accepts {@code CharSequence}. {@code null} elements are considered valid. *
  • @author djy */ @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {PatternNullableValidator.class}) public @interface PatternNullable {

    /**

    • @return the regular expression to match */ String regexp();

      /**

    • @return the error message template */ String message() default “{javax.validation.constraints.Pattern.message}”;

      /**

    • @return the groups the constraint belongs to */ Class<?>[] groups() default { };

      /**

    • @return the payload associated to the constraint */ Class<? extends Payload>[] payload() default { };

}

<a name="YBQPh"></a>
### 2、添加验证器PatternNullableValidator

- 解析注解用来验证那种类型的值,并且什么情况下进行放行。
```java
/*
 * Hibernate Validator, declare and validate application constraints
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
 */
package com.asto.tax.common.validation.annotation.validator;

import com.asto.tax.common.validation.annotation.PatternNullable;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext;
import org.hibernate.validator.internal.engine.messageinterpolation.util.InterpolationHelper;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.invoke.MethodHandles;
import java.util.regex.Matcher;
import java.util.regex.PatternSyntaxException;

/**
 * 如果是空值的就不验证了直接放行 有值才验证
 * @author djy
 */
public class PatternNullableValidator implements ConstraintValidator<PatternNullable, CharSequence> {

    private static final Log LOG = LoggerFactory.make(MethodHandles.lookup());

    private java.util.regex.Pattern pattern;
    private String escapedRegexp;

    @Override
    public void initialize(PatternNullable parameters) {
        try {
            pattern = java.util.regex.Pattern.compile(parameters.regexp());
        } catch (PatternSyntaxException e) {
            throw LOG.getInvalidRegularExpressionException(e);
        }

        escapedRegexp = InterpolationHelper.escapeMessageParameter(parameters.regexp());
    }

    @Override
    public boolean isValid(CharSequence value, ConstraintValidatorContext constraintValidatorContext) {
        if (value == null || value.length() == 0) {
            //如果是空值直接放行 不验证了
            return true;
        }

        if (constraintValidatorContext instanceof HibernateConstraintValidatorContext) {
            constraintValidatorContext.unwrap(HibernateConstraintValidatorContext.class).addMessageParameter("regexp", escapedRegexp);
        }

        Matcher m = pattern.matcher(value);
        return m.matches();
    }
}