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 | 必须符合该正则表达式 |
| 必须是电子邮箱格式 |
范围类型校验
| 注解 | 作用 |
|---|---|
| @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);
}
}
作者多数为原创文章 ( 部分转载已标出 ),目前资历尚浅文章内描述可能有误,对此造成的后果深表歉意,如有错误还望指正

浙公网安备 33010602011771号