1. 程式人生 > >數據驗證器

數據驗證器

field pty email enc charat val 年齡 convert 實體

  • 依賴

  • <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>2.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>javax.el</artifactId>
        <version>2.2.6</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.11.Final</version>
    </dependency>
    • 驗證器相關類

    /**
     * 驗證器接口
     */
    public interface Validator {
        /**
         * POJO實體驗證
         * @param entity
         * @param <T>
         * @return
         */
        <T> List<ValidateResult> validateEntity(T entity);
    
        /**
         * 方法參數驗證
         * @param obj
         * @param method
         * @param params
         * @param <T>
         * @return
         */
        <T> List<ValidateResult> validateMethodParams(T obj, Method method, Object[] params);
    }
    
    /**
     * 默認驗證.javax.validation
     */
    public class DefaultValidator implements Validator {
        private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        private final ExecutableValidator executableValidator = factory.getValidator().forExecutables();
        private final javax.validation.Validator validator = factory.getValidator();
    
        @Override
        public <T> List<ValidateResult> validateEntity(T entity) {
            Set<ConstraintViolation<T>> violationSet = validator.validate(entity);
            return convert(violationSet);
        }
    
        @Override
        public <T> List<ValidateResult> validateMethodParams(T obj, Method method, Object[] params) {
            Set<ConstraintViolation<T>> violationSet = executableValidator.validateParameters(obj, method, params);
            return convert(violationSet);
        }
    
        protected <T> List<ValidateResult> convert(Set<ConstraintViolation<T>> violationSet){
            if (violationSet == null || violationSet.isEmpty())
                return null;
            List<ValidateResult> resultList = new ArrayList<>(violationSet.size());
            for (ConstraintViolation cv : violationSet){
                String name = cv.getPropertyPath().toString();
                resultList.add(new ValidateResult(name, cv.getMessage(), cv.getInvalidValue()));
            }
            return resultList;
        }
    }
    
    /**
     * 驗證的結果
     */
    public class ValidateResult {
        /**
         * 驗證的字段名稱
         */
        private String name;
        /**
         * 提示信息
         */
        private String msg;
        /**
         * 驗證的值
         */
        private Object validatedVal;
    
        public ValidateResult(String name, String msg, Object validatedVal) {
            this.name = name;
            this.msg = msg;
            this.validatedVal = validatedVal;
        }
    
        @Override
        public String toString() {
            return "ValidateResult{" +
                    "name='" + name + '\'' +
                    ", msg='" + msg + '\'' +
                    ", validatedVal=" + validatedVal +
                    '}';
        }
    }
    • 自定義驗證器

    import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
    import static java.lang.annotation.ElementType.CONSTRUCTOR;
    import static java.lang.annotation.ElementType.FIELD;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.PARAMETER;
    import static java.lang.annotation.ElementType.TYPE_USE;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.Repeatable;
    import java.lang.annotation.Retention;
    import java.lang.annotation.Target;
    
    import javax.validation.Constraint;
    import javax.validation.Payload;
    
    /**
     * 自定義×××號碼驗證註解
     */
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Repeatable(IDCardNumber.List.class)
    @Documented
    @Constraint(validatedBy = {IDCardNumberValidator.class})
    public @interface IDCardNumber {
    
        String message() default "invalid IDCardNumber";
    
        Class<?>[] groups() default { };
    
        Class<? extends Payload>[] payload() default { };
    
    
        @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
        @Retention(RUNTIME)
        @Documented
        @interface List {
    
            IDCardNumber[] value();
        }
    }
    
    
    /**
     * IDCardNumber驗證器
     */
    public class IDCardNumberValidator implements ConstraintValidator<IDCardNumber, String> {
    
        @Override
        public void initialize(IDCardNumber constraintAnnotation) {
    
        }
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            if (null == value || "".equals(value))
                return false;
            if (value.length() != 18)
                return false;
            if (getValidateCode(value) != value.toUpperCase().charAt(17))
                return false;
            return true;
        }
    
        /**
         * 十七位數字本體碼權重
         */
        private static final int[] weight = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    
        /**
         * mod11,對應校驗碼字符值
         */
        private static final char[] validate = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    
        public char getValidateCode(String id17) {
            int sum = 0;
            int mode = 0;
            for (int i = 0; i < 17; i++) {
                //sum = sum + Integer.parseInt(String.valueOf(id17.charAt(i))) * weight[i];
                sum = sum + (id17.charAt(i) - 48) * weight[i];
            }
            mode = sum % 11;
            return validate[mode];
        }
    }
    • 測試

    @Valid
    public class User {
    
        @NotNull(message = "id不能為空")
        private Integer id;
        private String name;
        @NotNull(message = "郵箱不能為空")
        @Email(message = "不合法的郵箱")
        private String email;
        @IDCardNumber(message = "無效×××")
        private String IDCardNumber;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public String getIDCardNumber() {
            return IDCardNumber;
        }
    
        public void setIDCardNumber(String IDCardNumber) {
            this.IDCardNumber = IDCardNumber;
        }
    
        public void setField(@NotNull(message = "姓名不能為空") String name, @Range(min = 18, max = 60, message = "年齡只能在18至69歲") int age){}
    }
    
    public class Test {
        public static void main(String[] args) throws NoSuchMethodException {
            DefaultValidator defaultValidator = new DefaultValidator();
            User user = new User();
            user.setEmail("23424");
            user.setIDCardNumber("23424");
            List<ValidateResult> resultList = defaultValidator.validateEntity(user);
            System.out.println(resultList.toString());
    
            List<ValidateResult> validateResults = defaultValidator.validateMethodParams(user, user.getClass().getMethod("setField", String.class, int.class), new Object[]{null, 10});
            System.out.println(validateResults.toString());
        }
    }
    • 輸出結果

    [ValidateResult{name='id', msg='id不能為空', validatedVal=null}, 
    ValidateResult{name='IDCardNumber', msg='無效×××', validatedVal=23424}, 
    ValidateResult{name='email', msg='不合法的郵箱', validatedVal=23424}]
    
    [ValidateResult{name='setField.arg1', msg='年齡只能在18至69歲', validatedVal=10}, 
    ValidateResult{name='setField.arg0', msg='姓名不能為空', validatedVal=null}]














    數據驗證器