Spring Boot- Validation

Validation是什么

   Spring Boot Validation是Spring Boot整合了Hibernate Validation的一个框架,其核心是Hibernate Validation,此框架的作用是**检验客户端向服务器端提交的请求参数的基本格式是否合法**。

案例

    例如,当设计一个“登录”功能时,客户端可能需要向服务器端提交用户名、密码这2项数据,如果客户端没有提交用户名,或没有提交密码,这个请求必然是无效的,是不可能成功登录的,则服务器端应该直接响应一个错误信息,根本不需要连接数据库去验证用户信息是否正确!另外,如果客户端提交的用户名是例如`a`或` `(1个空格)这样的数据,很显然也是不合法的!此类对于数据的基本格式的检验,就可以通过Spring Boot Validation便捷的实现!

【需求】

使用Spring Boot框架实现用户登录(不关心如何验证用户名与密码),检验用户名和密码的基本格式。

【实现步骤】

1. 使用Spring Boot工程,在创建过程中需要注意:
   - 建议使用Spring Boot 2.5.x版本,如果已经没有此版本的选项,则选择2.6.x版本,非常不建议选择3.x.x版本
   - 需要勾选`Web > Spring Web`和`IO > Validation`这2个依赖项

2. 在项目的`com.fish.validation.demo`包中创建`UserController`类,作为控制器类,并在其中添加处理登录的方法:

  
   import org.springframework.web.bind.annotation.RequestMapping;
   import org.springframework.web.bind.annotation.RestController;
   
   @RestController
   public class UserController {
   
       // http://localhost:8080/login?username=root&password=1234
       @RequestMapping("/login")
       public String login(String username, String password) {
           System.out.println("username = " + username + ", password = " + password);
           return "OK";
       }
   
   }

3. 接下来,可以启动项目,并通过 http://localhost:8080/login?username=root&password=1234 测试访问,你还可以修改网址中的用户名和密码的值,在IntelliJ IDEA的控制台上会显示你提交的用户名和密码

4. 如果希望使用Spring Boot Validation验证请求参数的基本格式,应该将以上方法中接收的用户名和密码这2个数据封装起来,例如创建`UserLoginDTO`类,并在其中声明用户名和密码这2个属性,按照开发规范添加Setter & Getter方法,同时,为了便于查看数据,再生成`toString`方法,代码如下:


   
   public class UserLoginDTO {
   
       private String username;
       private String password;
   
       public String getUsername() {
           return username;
       }
   
       public void setUsername(String username) {
           this.username = username;
       }
   
       public String getPassword() {
           return password;
       }
   
       public void setPassword(String password) {
           this.password = password;
       }
   
       @Override
       public String toString() {
           return "UserLoginDTO{" +
                   "username='" + username + '\'' +
                   ", password='" + password + '\'' +
                   '}';
       }
       
   }
  

5. 接下来,原本处理请求的方法的参数就可以由2个字符串改为以上这1个类的对象:

  
   @RequestMapping("/login")
   public String login(UserLoginDTO userLoginDTO) {
       System.out.println("userLoginDTO = " + userLoginDTO);
       return "OK";
   }

6. 当需要验证请求参数的基本格式时,需要在以上方法的参数之前添加`@Valid`或`@Validated`注解(这2个注解是等效的),表示需要对此参数进行验证:


   @RequestMapping("/login")
   // 注意:下一行的参数添加了@Valid注解
   public String login(@Valid UserLoginDTO userLoginDTO) {
       System.out.println("userLoginDTO = " + userLoginDTO);
       return "OK";
   }

7. 接下来,在`UserLoginDTO`类的属性上,添加注解,以配置验证规则及出错时的提示文本,例如:

 
   public class UserLoginDTO {
   
       @NotNull(message = "登录失败,必须提交用户名!")
       private String username;
       private String password;
   
       // 省略后续代码
       
   }
   

8. 接下来,重新启动项目,提交一个没有用户名的请求,例如 http://localhost:8080/login?password=0000 ,则会提示错误,并且,在IntelliJ IDEA控制台可以看到:

 
   2022-03-30 20:09:35.270  WARN 10384 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'userLoginDTO' on field 'username': rejected value [null]; codes [NotNull.userLoginDTO.username,NotNull.username,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userLoginDTO.username,username]; arguments []; default message [username]]; default message [登录失败,必须提交用户名!]]
   

9. 提示:与`@NotNull`相似的注解还有`@NotBlank`、`@NotEmpty`,这几个是区别的:

   - `@NotNull`:不允许为`null`值,如果客户端提交的参数中根本没有这一项,则视为`null`
   - `@NotBlank`:不允许为空白值,空白值包括由若干个空格、`TAB`符等组成字符
   - `@NotEmpty`:不允许为空字符串,即不允许是长度为0的字符串

10. 当有必要的情况下,可以为属性添加多个验证的注解,例如:


    @NotNull(message = "登录失败,必须提交用户名!")
    @Pattern(regexp = "[a-zA-Z0-9_]{4,16}", message = "登录失败,用户名格式错误!")
    private String username;
    

11. 在控制器中,当需要获取验证失败时的提示文本(以上注解中配置的文本)时,需要在被验证的参数右侧添加`BindingResult`参数,例如:

  
    @RequestMapping("/login")
    public String login(@Valid UserLoginDTO userLoginDTO, BindingResult bindingResult) {
        // ...
    }

    注意:以上`BindingResult`参数必须直接添加在被验证对象的右侧,它们中间不可以添加其它参数!

12. 关于`BindingResult`的实用方法:


    // 判断验证是否不通过(存在错误)
    boolean hasError = bindingResult.hasErrors();
    
    // 获取验证失败的提示文本,如果有多个规则都没被满足,则是其中的不确定的某种提示文本
    String errorMessage = bindingResult.getFieldError().getDefaultMessage();
   

13. 关于更多Validation注解,可参考:https://blog.csdn.net/qq_20919883/article/details/106297523

14. 在实际应用中,当使用正则表达式时,应该将所有或相关的正则表达式都定义在一起(例如在同一个类或同一个接口中),各个类中的验证参数的正则表达式注解都从此处调用,便于统一管理这些正则表达式。

总结:

      Spring Boot Validation是一种用于验证和校验用户输入的框架。它提供了一种简便的方式来实现数据验证,从而确保应用程序接收到有效、合格的数据。

      在Spring Boot中,我们可以使用注解来定义验证规则。这些注解通常与实体类的属性一起使用,以指定所需的验证条件。常用的验证注解包括@NotNull、@Size、@Min、@Max、@Email等。

       验证注解可以应用在实体类的属性上,也可以应用在方法的参数上。它们可以指定验证的条件,例如非空、长度范围、数字范围、邮箱格式等。

       在应用程序中,当收到用户的输入时,Spring Boot Validation会自动根据注解的配置来进行验证。如果验证失败,将会抛出一个ValidationException异常。我们可以使用全局异常处理器来捕获并处理这个异常,以返回正确的错误信息给用户。

     除了使用注解来进行验证,Spring Boot Validation还支持自定义验证规则。我们可以实现ConstraintValidator接口,编写自定义的验证逻辑。通过在注解中引用自定义验证器,可以将自定义验证规则应用于实体类的属性或方法参数上。

    Spring Boot Validation还提供了一些额外的功能,例如分组验证和嵌套验证。分组验证可以根据不同的场景对实体类的属性进行不同的验证,以满足不同的业务需求。嵌套验证允许我们在实体类中嵌套使用其他实体类,并对其进行递归验证。

      

相关推荐

  1. Springboot整合hibernate validator 全局异常处理

    2024-03-13 11:22:03       44 阅读
  2. Springboot】参数校验 spring-boot-starter-validation

    2024-03-13 11:22:03       55 阅读
  3. springboot @Validated的概念以及实战

    2024-03-13 11:22:03       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-13 11:22:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-13 11:22:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-13 11:22:03       82 阅读
  4. Python语言-面向对象

    2024-03-13 11:22:03       91 阅读

热门阅读

  1. LeetCode题练习与总结:搜索旋转排序数组

    2024-03-13 11:22:03       39 阅读
  2. 【leetcode热题】反转字符串中的单词

    2024-03-13 11:22:03       46 阅读
  3. 焦点调制网络

    2024-03-13 11:22:03       42 阅读
  4. 蓝桥杯历年真题省赛之 2016年 第七届 生日蜡烛

    2024-03-13 11:22:03       31 阅读
  5. Kafka吞吐量高的原因

    2024-03-13 11:22:03       35 阅读
  6. 阿里云国际修改域名绑定的DDoS高防服务器

    2024-03-13 11:22:03       40 阅读
  7. RUST 每日一省:迭代器1

    2024-03-13 11:22:03       42 阅读
  8. 【Rust日报】Ascent:在 Rust 中嵌入的逻辑编程语言

    2024-03-13 11:22:03       36 阅读
  9. Linux中一些基础命令

    2024-03-13 11:22:03       45 阅读
  10. 自动点名器

    2024-03-13 11:22:03       41 阅读