Skip to content

前言

做web开发有一点很烦人就是要校验参数,基本上每个接口都要对参数进行校验,比如一些格式校验、非空校验都是必不可少的。如果参数比较少的话还是容易处理,但参数比较多了的话代码中就会出现大量的IF ELSE就比如下面这样: 这个例子只是校验了一下空参数。如果需要验证邮箱格式和手机号格式校验的话代码会更多,所以介绍一下validator通过注解的方式进行校验参数。

什么是Validator

Bean Validation是Java定义的一套基于注解的数据校验规范,定义于JSR 303规范(JAVA EE6的字规范)。

Hibernate Validator是Bean Validation的参考实现,提供了JSR-303 规范中所有内置constraint的实现,除此之外Hibernate Validator还附加了一些constraint。

SpringBoot(2.3以下版本)中已经集成在 starter-web中,所以无需在添加其他依赖。在Springboot 2.3以上版本需单独引入:

xml
       <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) | 被注释的元素必须符合指定的正则表达式 | | | | @Email | 被注释的元素必须是电子邮箱地址 | Hibernate Validator 附加的 constraint |

注意:

  • @NotNull 适用于任何类型,被注解的元素必须不能与NULL
  • @NotEmpty 适用于String、collection、Map或者数组,不能为Null且长度必须大于0 (String可以为空字符串)
  • @NotBlank 只能用于String上面,不能为null,也不能为纯空格的字符串

使用

实体类校验

模拟用户注册封装了一个UserDTO 然后需要在controller方法体添加@Validated不加@Validated校验会不起作用

参数校验

在开发的时候一定遇到过单个参数的情况,在参数前面加上注解即可

java
@PostMapping("/get")
public ReturnVO getUserInfo(@RequestParam("userId")  @NotNull(message = "用户ID不能为空") String userId){
 	//...
}

正则校验

使用正则校验手机号

java
    /**
     * 手机号
     */
    @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;

自定义注解

上面的注解只有这么多,如果有特殊校验的参数我们可以使用Validator自定义注解进行校验。 首先创建一个IdCard注解:

java
@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方法,传入参数就是手机号。

然后使用在实体类中使用:

java
    @NotNull(message = "身份证号不能为空")
    @IdCard(message = "身份证不合法")
    private String IdCardNumber;

分组

就比如上面我们定义的UserDTO中的参数如果要服用的话怎么办? 在重新定义一个类然后里面的参数要重新添加注解? Validator提供了分组方法完美了解决实体类校验复用问题。

1.先创建分组的接口:

java
public interface Create  extends Default { }

2.在注解加入分组参数:

java
  /**
     * 用户名
     */
    @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

java
    @PostMapping("/user")
    public ReturnVO userRegistra(@RequestBody @Validated(Create.class) UserDTO userDTO){
        ReturnVO returnVO = userService.userRegistra(userDTO);
        return returnVO ;
    }