Loading

JSR303数据校验使用方法记录

JSR303并不对应着指定的jar包,而是一种规范,目前hibernate-validator是使用最多的是基于JSR303规范的实现

本文不适合新人观看,要求至少要知道使用方法

Springboot整合JSR303的starter启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

正常引用hibernate-validator的依赖

<!-- 6.2.0.Final是推荐使用的版本 -->
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.2.0.Final</version>
</dependency>

常用注解记录

这里记录一些常见常用的注解,并非全部,如有遇到会随时补充

注解简单介绍

每个注解都包含通用属性,这里介绍一下message和groups:

注解 作用
message 字符串,报错后提示的错误信息
groups 接口的class属性,为校验分组

值类型校验

注解 作用
@Null 必须为Null
@NotNull 必须不为Null
@NotBlank 必须不为空(去除首位空格)
@NotEmpty 效果等同于@NotBlank
@AssertTrue 必须为true
@AssertFalse 必须为false
@Pattren 必须符合该正则表达式
@Email 必须是电子邮箱格式

范围类型校验

注解 作用
@Min 必须是数字且大于等于指定的数字
@Max 必须是数字且小于等于指定的数字
@Range 必须是数字且大于等于min,小于等于max
@DecimalMin 必须是数字且大于等于指定的数字
@DecimalMax 必须是数字且小于等于指定的数字
@Digits 必须是数字且整数位不能超过integer位,小数位不能超过fraction
@Length 必须是字符串且大于等于min并且小于等于max
@Size 适用于字符串集合数组,长度大于等于min并且小于等于max
@Past 必须是过去的日期
@Future 必须是将来的日期

自定义校验注解

自定义校验注解需要创建一个注解,然后加上每个校验注解都有的三个基本属性

@Documented
@Target({ METHOD, FIELD, PARAMETER })
@Retention(RUNTIME)
public @interface Phone {

    String message() default "";

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

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

}

现在注解就创建完成了,但是是个没用的空壳注解,想要让他拥有校验的能力需要一个类来帮他完成校验,使用@Constraint注解来指定让哪个类来帮自己完成校验

@Documented
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
// 表示要用PhoneValidate来帮自己完成校验
@Constraint(validatedBy = PhoneValidate.class)
public @interface Phone { ... }

接下来创建PhoneValidate类来帮注解完成校验规则

// 该类必须实现ConstraintValidator接口,泛型中的Phone代表生效的注解,String代表被注解的属性的类型
public class PhoneValidate implements ConstraintValidator<Phone, String> {

    // private String pattern;

    @Override
    public void initialize(Phone annotation) {
        // 这里执行优先级高,可以通过annotation获取到注解中携带的值,用于后续校验处理,例如:
        // this.pattern = annotation.pattern();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 通过返回true或false来决定校验是否通过
        String regExp = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(166)|(17[3,5,6,7,8])|(18[0-9])|(19[8,9]))\\d{8}$";
        return value.matches(regExp);
    }

}

全局异常处理

Contrller层的实体类加上@Valid注解后会开启参数校验,未通过校验规则会抛出异常,针对异常可以通过全局异常处理优雅的返回错误信息,这里就不写那么细了,直接将方法粘过来

@Slf4j
@RestControllerAdvice
public class ExceptionControllerAdvice {
    
    /** JSR303参数校验失败异常 */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Map<String, String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        // 获取参数异常信息
        BindingResult bindingResult = e.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        // 创建Map集合,用于存储异常信息返回给页面
        Map<String, String> errors = new HashMap<>();
        fieldErrors.forEach(item -> errors.put(item.getField(), item.getDefaultMessage()));
        
		return errors;
		// 这个R是自己项目中封装的通用返回模板
        // return R.error(BizCodeMenu.VALID_EXCEPTION).put("data", errors);
    }
    
}
posted @ 2021-11-08 22:44  Java小学生丶  阅读(110)  评论(0)    收藏  举报