数据验证器

  • 依赖

<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}]







扫描二维码关注公众号,回复: 2370421 查看本文章








猜你喜欢

转载自blog.51cto.com/881206524/2150137