SpringMVC参数校验

时间:2024-5-30    作者:老大夫    分类: SSM


  1. 在实体类中添加校验注解
  2. 在Controller的handler中给参数添加@Validate注解,param和JSON都有效果

5.3 参数校验

在 Web 应用三层架构体系中,表述层负责接收浏览器提交的数据,业务逻辑层负责数据的处理。为了能够让业务逻辑层基于正确的数据进行处理,我们需要在表述层对数据进行检查,将错误的数据隔绝在业务逻辑层之外。

  1. 校验概述

    JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 标准中。JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证。

    注解 规则
    @Null 标注值必须为 null
    @NotNull 标注值不可为 null
    @AssertTrue 标注值必须为 true
    @AssertFalse 标注值必须为 false
    @Min(value) 标注值必须大于或等于 value
    @Max(value) 标注值必须小于或等于 value
    @DecimalMin(value) 标注值必须大于或等于 value
    @DecimalMax(value) 标注值必须小于或等于 value
    @Size(max,min) 标注值大小必须在 max 和 min 限定的范围内
    @Digits(integer,fratction) 标注值值必须是一个数字,且必须在可接受的范围内
    @Past 标注值只能用于日期型,且必须是过去的日期
    @Future 标注值只能用于日期型,且必须是将来的日期
    @Pattern(value) 标注值必须符合指定的正则表达式
    JSR 303 只是一套标准,需要提供其实现才可以使用。Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
    注解 规则
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------
    @Email 标注值必须是格式正确的 Email 地址
    @Length 标注值字符串大小必须在指定的范围内
    @NotEmpty 标注值字符串不能是空字符串
    @Range 标注值必须在指定的范围内
    Spring 4.0 版本已经拥有自己独立的数据校验框架,同时支持 JSR 303 标准的校验框架。Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。在SpringMVC 中,可直接通过注解驱动 @EnableWebMvc 的方式进行数据校验。Spring 的 LocalValidatorFactoryBean 既实现了 Spring 的 Validator 接口,也实现了 JSR 303 的 Validator 接口。只要在Spring容器中定义了一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的 Bean中。Spring本身并没有提供JSR 303的实现,所以必须将JSR 303的实现者的jar包放到类路径下。
    配置 @EnableWebMvc后,SpringMVC 会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注 @Validated 注解即可让 SpringMVC 在完成数据绑定后执行数据校验的工作。
  2. 操作演示

    • 导入依赖

      <!-- 校验注解 -->
      <dependency>
       <groupId>jakarta.platform</groupId>
       <artifactId>jakarta.jakartaee-web-api</artifactId>
       <version>9.1.0</version>
       <scope>provided</scope>
      </dependency>
      
      <!-- 校验注解实现-->        
      <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
      <dependency>
       <groupId>org.hibernate.validator</groupId>
       <artifactId>hibernate-validator</artifactId>
       <version>8.0.0.Final</version>
      </dependency>
      <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
      <dependency>
       <groupId>org.hibernate.validator</groupId>
       <artifactId>hibernate-validator-annotation-processor</artifactId>
       <version>8.0.0.Final</version>
      </dependency>
    • 应用校验注解

      import jakarta.validation.constraints.Email;
      import jakarta.validation.constraints.Min;
      import org.hibernate.validator.constraints.Length;
      
      /**
      * projectName: com.atguigu.pojo
      */
      public class User {
       //age   1 <=  age < = 150
       @Min(10)
       private int age;
      
       //name 3 <= name.length <= 6
       @Length(min = 3,max = 10)
       private String name;
      
       //email 邮箱格式
       @Email
       private String email;
      
       public int getAge() {
           return age;
       }
      
       public void setAge(int age) {
           this.age = age;
       }
      
       public String getName() {
           return name;
       }
      
       public void setName(String name) {
           this.name = name;
       }
      
       public String getEmail() {
           return email;
       }
      
       public void setEmail(String email) {
           this.email = email;
       }
      }
      
    • handler标记和绑定错误收集

      @RestController
      @RequestMapping("user")
      public class UserController {
      
       /**
        * @Validated 代表应用校验注解! 必须添加!
        */
       @PostMapping("save")
       public Object save(@Validated @RequestBody User user,
                          //在实体类参数和 BindingResult 之间不能有任何其他参数, BindingResult可以接受错误信息,避免信息抛出!
                          BindingResult result){
          //判断是否有信息绑定错误! 有可以自行处理!
           if (result.hasErrors()){
               System.out.println("错误");
               String errorMsg = result.getFieldError().toString();
               return errorMsg;
           }
           //没有,正常处理业务即可
           System.out.println("正常");
           return user;
       }
      }
    • 测试效果

  3. 易混总结

    @NotNull、@NotEmpty、@NotBlank 都是用于在数据校验中检查字段值是否为空的注解,但是它们的用法和校验规则有所不同。

    1. @NotNull (包装类型不为null)

      @NotNull 注解是 JSR 303 规范中定义的注解,当被标注的字段值为 null 时,会认为校验失败而抛出异常。该注解不能用于字符串类型的校验,若要对字符串进行校验,应该使用 @NotBlank 或 @NotEmpty 注解。

    2. @NotEmpty (集合类型长度大于0)

      @NotEmpty 注解同样是 JSR 303 规范中定义的注解,对于 CharSequence、Collection、Map 或者数组对象类型的属性进行校验,校验时会检查该属性是否为 Null 或者 size()==0,如果是的话就会校验失败。但是对于其他类型的属性,该注解无效。需要注意的是只校验空格前后的字符串,如果该字符串中间只有空格,不会被认为是空字符串,校验不会失败。

    3. @NotBlank (字符串,不为null,切不为" "字符串)

      @NotBlank 注解是 Hibernate Validator 附加的注解,对于字符串类型的属性进行校验,校验时会检查该属性是否为 Null 或 “” 或者只包含空格,如果是的话就会校验失败。需要注意的是,@NotBlank 注解只能用于字符串类型的校验。
      总之,这三种注解都是用于校验字段值是否为空的注解,但是其校验规则和用法有所不同。在进行数据校验时,需要根据具体情况选择合适的注解进行校验。


扫描二维码,在手机上阅读

推荐阅读: