前言
做web开发有一点很烦人就是要校验参数,基本上每个接口都要对参数进行校验,比如一些格式校验、非空校验都是必不可少的。如果参数比较少的话还是容易处理,但参数比较多了的话代码中就会出现大量的IF ELSE就比如下面这样:
这个例子只是校验了一下空参数。如果需要验证邮箱格式和手机号格式校验的话代码会更多,所以介绍一下validator通过注解的方式进行校验参数。
什么是Validator
<font style="color:#1890FF;">Bean Validation</font>
是Java定义的一套基于注解的数据校验规范,定义于JSR 303规范()。
<font style="color:#1890FF;">Hibernate Validator</font>
<font style="color:#1890FF;">Hibernate Validator</font>
在SpringBoot
(2.3以下版本)中已经集成在 starter-web中,所以无需在添加其他依赖。在Springboot
2.3以上版本需单独引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
注解介绍
分组 | 注解 | 详细信息 | 备注 |
---|---|---|---|
空和非空校验 | @Null | 被注释的元素必须为 null | **** |
@NotNull | 被注释的元素必须不为 null | **** | |
@NotBlank | 验证字符串非null,且长度必须大于0 | Hibernate Validator 附加的 constraint | |
@NotEmpty | 被注释的字符串的必须非空 | Hibernate Validator 附加的 constraint | |
布尔值校验 | @AssertTrue | 被注释的元素必须为 true | |
@AssertFalse | 被注释的元素必须为 false | ||
数值校验 | @Min(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 | |
@Max(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 | ||
@DecimalMin(value) | 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 | ||
@DecimalMax(value) | 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 | ||
@Size(max, min) | 被注释的元素的大小必须在指定的范围内 | ||
@Digits (integer, fraction) | 被注释的元素必须是一个数字,其值必须在可接受的范围内 | ||
@Negative | 必须为负整数 | ||
@Positive | 必须为正整数 | ||
日期校验 | @Past | 被注释的元素必须是一个过去的日期 | |
@PastOrPresent | 被注释的元素必须是当前或过去的日期 | ||
@Future | 被注释的元素必须是一个将来的日期 | ||
@FutureOrPresent | 被注释的元素必须是一个当前或将来的日期 | ||
其他 | @Pattern(value) | 被注释的元素必须符合指定的正则表达式 | |
被注释的元素必须是电子邮箱地址 | Hibernate Validator 附加的 constraint |
- @NotNull 适用于任何类型,被注解的元素必须不能与NULL
- @NotEmpty 适用于String、collection、Map或者数组,不能为Null且长度必须大于0 (String可以为空字符串)
- @NotBlank 只能用于String上面,不能为null,也不能为纯空格的字符串
使用
实体类校验
模拟用户注册封装了一个UserDTO
然后需要在controller方法体添加@Validated不加@Validated校验会不起作用
参数校验
在开发的时候一定遇到过单个参数的情况,在参数前面加上注解即可
@PostMapping("/get")
public ReturnVO getUserInfo(@RequestParam("userId") @NotNull(message = "用户ID不能为空") String userId){
//...
}
正则校验
使用正则校验手机号
/**
* 手机号
*/
@NotNull(message = "手机号不能为空")
@NotBlank(message = "手机号不能为空")
@Pattern(regexp ="^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误")
@Max(value = 11,message = "手机号只能为{max}位")
@Min(value = 11,message = "手机号只能为{min}位")
private String mobileNo;
自定义注解
上面的注解只有这么多,如果有特殊校验的参数我们可以使用进行校验。
首先创建一个IdCard注解:
@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdCardValidator.class)
public @interface IdCard {
String message() default "身份证号码不合法";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
在UserDTO中添加@IdCard
注解即可验证,在运行时触发。
然后添加IdCardValidator
主要进行验证逻辑
上面调用了is18ByteIdCardComplex
方法,传入参数就是手机号。
然后使用在实体类中使用:
@NotNull(message = "身份证号不能为空")
@IdCard(message = "身份证不合法")
private String IdCardNumber;
分组
就比如上面我们定义的UserDTO中的参数如果要服用的话怎么办?
在重新定义一个类然后里面的参数要重新添加注解?
Validator提供了分组方法完美了解决实体类校验复用问题。
1.先创建分组的接口:
public interface Create extends Default { }
2.在注解加入分组参数:
/**
* 用户名
*/
@NotBlank(message = "用户姓名不能为空",groups = Create.class)
@NotNull(message = "用户姓名不能为空",groups = Create.class)
private String userName;
@NotBlank(message = "邮箱不能为空",groups = Update.class)
@NotNull(message = "邮箱不能为空",groups = Update.class)
@Email(message = "邮箱格式错误",groups = Update.class)
private String email;
3.然后在修改Controller在@Validated中传入Create.class
@PostMapping("/user")
public ReturnVO userRegistra(@RequestBody @Validated(Create.class) UserDTO userDTO){
ReturnVO returnVO = userService.userRegistra(userDTO);
return returnVO ;
}