【SpringBoot】使用 Javax Validator 进行属性校验

122 阅读2分钟

痛点

直接上图👇

image.png

不知道各位程序员有没有为上面红色字体的属性判空整无语过..感觉十分冗杂,所以..它被干掉了 取而代之的是下面绿色字体的代码(果然生活还是要带点绿,无论是头顶还是基金)

取而代之的是,使用JAVAX Validator + Annotation 的方式对对象的属性进行校验

实现

校验结果类 ValidationResult

public class ValidationResult {

    private boolean hasError = false;

    private Map<String, String> errorMsgMap = new HashMap<>();

    public String getAllErrorMsg() {
        return StringUtils.join(this.errorMsgMap.values().toArray(), ",");
    }

    public boolean isHasError() {
        return hasError;
    }

    public void setHasError(boolean hasError) {
        this.hasError = hasError;
    }

    public Map<String, String> getErrorMsgMap() {
        return errorMsgMap;
    }

    public void setErrorMsgMap(Map<String, String> errorMsgMap) {
        this.errorMsgMap = errorMsgMap;
    }
}

校验结果类比较简单,主要用于记录是否有校验不合法的情况(hasError),有的话就把他存在hashMao(errMsgMap)中,剩下的都是get/set方法了


校验实现类 ValidatorImpl

@Component
public class ValidatorImpl implements InitializingBean {
    private Validator validator;

    public ValidationResult validate(Object bean) {
        final ValidationResult result = new ValidationResult();
        Set<ConstraintViolation<Object>> constraintViolationSet = validator.validate(bean);

        if (constraintViolationSet.size() > 0) {
            result.setHasError(true);
            constraintViolationSet.forEach(constraintViolation -> {
                String type = constraintViolation.getPropertyPath().toString();
                String msg = constraintViolation.getMessage();
                result.getErrorMsgMap().put(type, msg);
            });
        }

        return result;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.validator = Validation.buildDefaultValidatorFactory().getValidator();
    }
}

主要通过 buildDefaultValidatorFactory 方法拿到javax的validator,用该validator在校验实现方法 validate 中去校验形参的Object对象,校验结果会存到一个Set中去,最后把set里面的错误信息全部取出来,封装成一个 ValidationResult 对象并返回

要注意要把该类放进IOC容器,后面使用的时候需要自动装载

校验规则怎么定义的呢? Answer:通过在类中对属性添加注解即可


校验规则定义

见下方代码中的注解

下面我分别使用了 javax.validation.constraintsorg.hibernate.validator.constraints 两个包中的注解,均能生效

public class UserModel {
    private Integer id;

    @NotBlank(message = "请输入用户名")
    private String name;

    @NotNull(message = "请输入性别")
    private Integer sex;

    @NotNull(message = "请输入年龄")
    @Range(min = 0, max = 120, message = "年龄需要在0~120岁之间")
    private Integer age;

    @NotBlank(message = "请输入手机号")
    @Length(min = 11, max = 11, message = "请输入合法的手机号")
    private String telphone;

    private String registerMode;

    private String thirdPartyId;

    @NotBlank(message = "请输入密码")
    @Length(min = 6, max = 20, message = "请输入至少6位密码")
    private String encrptPassword;
}

org.hibernate.validator.constraints的maven依赖如下

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>5.2.4.Final</version>
</dependency>

使用

简简单单👇

@Autowired
private ValidatorImpl validator;

ValidationResult result = validator.validate(userModel);
if (result.isHasError()) { //数据校验不正确,抛出异常
    throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getAllErrorMsg());
}