Skip to content

前言

做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以上版本需单独引入:

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

注解介绍

分组注解详细信息备注


空和非空校验
@Null被注释的元素必须为 null****
@NotNull被注释的元素必须不为 null****
@NotBlank验证字符串非null,且长度必须大于0Hibernate 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;

自定义注解

上面的注解只有这么多,如果有特殊校验的参数我们可以使用进行校验。

首先创建一个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 ;
    }