在正常的业务处理中,针对外部的情况,校验参数的合法性是必须的,而在Spring MVC中有两种验证方式:Spring自带的验证框架和基于JSR实现的框架。

其中JSR(JSR303/SR-349)是一个规范文档,规定一些校验规范。Hibernate Validator就是基于JSR303规范的具体实现,提供了JSR 规范中内置约束注解的实现,同时附加了一些约束注解。

当然,用户也可以可以自定义约束注解。

依赖引入

当我们引入spring-boot-starter-web时,该starter会默认引入hibernate-validator,也就是Hibernate Validator框架。Spring Boot的参数校验正是依赖于Hibernate Validator框架来进行。

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

上述start中间接引入如下配置:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
  <version>2.2.2.RELEASE</version>
  <scope>compile</scope>
  <exclusions>
    <exclusion>
      <artifactId>tomcat-embed-el</artifactId>
      <groupId>org.apache.tomcat.embed</groupId>
    </exclusion>
  </exclusions>
</dependency>

在校验数据时,需要定义对应的数据模型(Java Bean),通过注解来指定字段校验的规则,下面具体的实例来进行演示。

实例

Controller中对订单进行参数信息进行校验。首先定义Order对象,并在其内通过注解对其属性进行约束。

@Data
public class Order {

    @NotEmpty(message = "请求流水号不能为空")
    private String requestNo;

    @Min(value = 1,message = "至少购买1件")
    @Max(value = 10,message = "最多不超过10件")
    private int amount;

    @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
    @NotBlank(message = "手机号码不能为空")
    private String phone;

    private String goodsName;

}

在Controller中的方法中使用Order作为参数,并通过添加@Valid注解开启校验。

@Slf4j
@RestController
public class OrderController {

    @PostMapping("/buy")
    public void buy(@Valid Order order, BindingResult result) {

        log.info("请求order信息:{}", order);

        if (result.hasErrors()) {
            result.getAllErrors().forEach((error) -> {
                System.out.println(error.getCode() + "-" + error.getDefaultMessage());
            });
        }
    }
}

其中buy方法的参数BindingResult用于存储校验结果信息,可以通过其hasErrors方法来判断是否校验通过,校验不通过时可以将错误信息打印出来或进行返回。

BindingResult必须跟在被校验参数之后,若被校验参数之后没有BindingResult对象,将会抛出BindException。

需要注意的是@Valid和BindingResult是一一对应的,如果有多个@Valid,那么每个@Valid后面都需要添加BindingResult用于接收Bean中的校验信息,顺序不能乱。

单元测试方法如下:

@Test
void buy() throws Exception {
    mockMvc.perform(
            MockMvcRequestBuilders.post("/buy")
                    .param("requestNo", "")
                    .param("amount", "0")
                    .param("phone", "11111111111")
    );
}

执行结果打印:

请求order信息:Order(requestNo=, amount=0, phone=11111111111, goodsName=null)
Pattern-手机号码格式错误
NotEmpty-请求流水号不能为空
Min-至少购买1件

常用校验注解

  • @Null:限制只能为null。
  • @NotNull:限制必须不为null。
  • @AssertFalse:限制必须为false。
  • @AssertTrue:限制必须为true。
  • @DecimalMax(value):限制必须为一个不大于指定值的数字。
  • @DecimalMin(value):限制必须为一个不小于指定值的数字。
  • @Digits(integer,fraction):限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction。
  • @Future:限制必须是一个将来的日期。
  • @Max(value):限制必须为一个不大于指定值的数字。
  • @Min(value):限制必须为一个不小于指定值的数字。
  • @Past:限制必须是一个过去的日期。
  • @Pattern(value):限制必须符合指定的正则表达式。
  • @Size(max,min):限制字符长度必须在min到max之间。
  • @Past:验证注解的元素值(日期类型)比当前时间早。
  • @NotEmpty:验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)。
  • @NotBlank:验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格。
  • @Email:验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式。

SpringBoot技术视频

CSDN学院:《Spring Boot 视频教程全家桶》



SpringBoot2.x系列教程Validation数据校验基础使用插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://www.choupangxia.com/2020/01/08/springboot2-x-validation/