一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!

沙海 2021年7月7日12:22:14Java评论36字数 3982阅读13分16秒阅读模式
摘要

智能摘要

智能摘要文章源自JAVA秀-https://www.javaxiu.com/36698.html

这样的代码,小伙伴们在日常开发中一定不少见,很多开源项目都是这样对请求入参做校验的。不了解的朋友一定要好好看一下,学完马上就可以实践到项目上去。一定一定不要忘记在类上加上Validated注解了,这个参数可以告诉Spring去校验方法参数。当我们对对象操作的不同方法有不同的验证规则的时候才会用到验证组。文章源自JAVA秀-https://www.javaxiu.com/36698.html

原文约 2666 | 图片 42 | 建议阅读 6 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!

小黑格子屋 文章源自JAVA秀-https://www.javaxiu.com/36698.html

以下文章来源于JavaGuide,作者Guide哥文章源自JAVA秀-https://www.javaxiu.com/36698.html

文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

JavaGuide文章源自JAVA秀-https://www.javaxiu.com/36698.html

专注Java后端学习和大厂面试的公众号!开源项目—JavaGuide (88k+Star)作者运营维护。学习Java,首选JavaGuide!文章源自JAVA秀-https://www.javaxiu.com/36698.html

文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

来源:JavaGuide文章源自JAVA秀-https://www.javaxiu.com/36698.html

作者:Guide哥文章源自JAVA秀-https://www.javaxiu.com/36698.html

数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。文章源自JAVA秀-https://www.javaxiu.com/36698.html

最普通的做法就像下面这样。我们通过 if/else 语句对请求的每一个参数一一校验。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

这样的代码,小伙伴们在日常开发中一定不少见,很多开源项目都是这样对请求入参做校验的。文章源自JAVA秀-https://www.javaxiu.com/36698.html

但是,不太建议这样来写,这样的代码明显违背了 单一职责原则。大量的非业务代码混杂在业务代码中,非常难以维护,还会导致业务层代码冗杂!文章源自JAVA秀-https://www.javaxiu.com/36698.html

实际上,我们是可以通过一些简单的手段对上面的代码进行改进的!这也是本文主要要介绍的内容!文章源自JAVA秀-https://www.javaxiu.com/36698.html

废话不多说!下面我会结合自己在项目中的实际使用经验,通过实例程序演示如何在 SpringBoot 程序中优雅地的进行参数验证(普通的 Java 程序同样适用)。文章源自JAVA秀-https://www.javaxiu.com/36698.html

不了解的朋友一定要好好看一下,学完马上就可以实践到项目上去。文章源自JAVA秀-https://www.javaxiu.com/36698.html

并且,本文示例项目使用的是目前最新的 Spring Boot 版本 2.4.5!(截止到 2021-04-21)文章源自JAVA秀-https://www.javaxiu.com/36698.html

示例项目源代码地址:https://github.com/CodingDocs/springboot-guide/tree/master/source-code/bean-validation-demo文章源自JAVA秀-https://www.javaxiu.com/36698.html

添加相关依赖

如果开发普通 Java 程序的的话,你需要可能需要像下面这样依赖:文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

不过,相信大家都是使用的 Spring Boot 框架来做开发。文章源自JAVA秀-https://www.javaxiu.com/36698.html

基于 Spring Boot 的话,就比较简单了,只需要给项目添加上 spring-boot-starter-web 依赖就够了,它的子依赖包含了我们所需要的东西。另外,我们的示例项目中还使用到了 Lombok。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

但是!!!Spring Boot 2.3 1 之后,spring-boot-starter-validation 已经不包括在了 spring-boot-starter-web 中,需要我们手动加上!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

验证 Controller 的输入

验证请求体

验证请求体即使验证被 @RequestBody 注解标记的方法参数。文章源自JAVA秀-https://www.javaxiu.com/36698.html

PersonController文章源自JAVA秀-https://www.javaxiu.com/36698.html

我们在需要验证的参数上加上了@Valid注解,如果验证失败,它将抛出MethodArgumentNotValidException。默认情况下,Spring 会将此异常转换为 HTTP Status 400(错误请求)。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

PersonRequest文章源自JAVA秀-https://www.javaxiu.com/36698.html

我们使用校验注解对请求的参数进行校验!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

正则表达式说明:文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • ^string : 匹配以 string 开头的字符串文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • string$ :匹配以 string 结尾的字符串文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • ^string$ :精确匹配 string 字符串文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • (^Man$|^Woman$|^UGM$) : 值只能在 Man,Woman,UGM 这三个值中选择文章源自JAVA秀-https://www.javaxiu.com/36698.html

GlobalExceptionHandler文章源自JAVA秀-https://www.javaxiu.com/36698.html

自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。如果对于下面的处理异常的代码不太理解的话,可以查看这篇文章 《SpringBoot 处理异常的几种常见姿势》文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

通过测试验证文章源自JAVA秀-https://www.javaxiu.com/36698.html

下面我通过 MockMvc 模拟请求 Controller 的方式来验证是否生效。当然了,你也可以通过 Postman 这种工具来验证。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

使用 Postman 验证文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

验证请求参数

验证请求参数(Path Variables 和 Request Parameters)即是验证被 @PathVariable 以及 @RequestParam 标记的方法参数。文章源自JAVA秀-https://www.javaxiu.com/36698.html

PersonController文章源自JAVA秀-https://www.javaxiu.com/36698.html

一定一定不要忘记在类上加上 Validated 注解了,这个参数可以告诉 Spring 去校验方法参数。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

ExceptionHandler文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

通过测试验证文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

使用 Postman 验证文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

验证 Service 中的方法

我们还可以验证任何 Spring Bean 的输入,而不仅仅是 Controller 级别的输入。通过使用@Validated@Valid注释的组合即可实现这一需求!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一般情况下,我们在项目中也更倾向于使用这种方案。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一定一定不要忘记在类上加上 Validated 注解了,这个参数可以告诉 Spring 去校验方法参数。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

通过测试验证:文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

输出结果如下:文章源自JAVA秀-https://www.javaxiu.com/36698.html

name 不能为空sex 值不在可选范围

Validator 编程方式手动进行参数验证

某些场景下可能会需要我们手动校验并获得校验结果。文章源自JAVA秀-https://www.javaxiu.com/36698.html

我们通过 Validator 工厂类获得的 Validator 示例。另外,如果是在 Spring Bean 中的话,还可以通过 @Autowired 直接注入的方式。文章源自JAVA秀-https://www.javaxiu.com/36698.html

@AutowiredValidator validate

具体使用情况如下:文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

输出结果如下:文章源自JAVA秀-https://www.javaxiu.com/36698.html

sex 值不在可选范围name 不能为空

自定以 Validator(实用)

如果自带的校验注解无法满足你的需求的话,你还可以自定义实现注解。文章源自JAVA秀-https://www.javaxiu.com/36698.html

案例一:校验特定字段的值是否在可选范围

比如我们现在多了这样一个需求:PersonRequest 类多了一个 Region 字段,Region 字段只能是ChinaChina-TaiwanChina-HongKong这三个中的一个。文章源自JAVA秀-https://www.javaxiu.com/36698.html

第一步,你需要创建一个注解 Region文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

第二步,你需要实现 ConstraintValidator接口,并重写isValid 方法。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

现在你就可以使用这个注解:文章源自JAVA秀-https://www.javaxiu.com/36698.html

@Regionprivate String region;

通过测试验证文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

使用 Postman 验证文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

案例二:校验电话号码

校验我们的电话号码是否合法,这个可以通过正则表达式来做,相关的正则表达式都可以在网上搜到,你甚至可以搜索到针对特定运营商电话号码段的正则表达式。文章源自JAVA秀-https://www.javaxiu.com/36698.html

PhoneNumber.java文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

PhoneNumberValidator.java文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

搞定,我们现在就可以使用这个注解了。文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

通过测试验证文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

使用验证组

验证组我们基本是不会用到的,也不太建议在项目中使用,理解起来比较麻烦,写起来也比较麻烦。简单了解即可!文章源自JAVA秀-https://www.javaxiu.com/36698.html

当我们对对象操作的不同方法有不同的验证规则的时候才会用到验证组。文章源自JAVA秀-https://www.javaxiu.com/36698.html

我写一个简单的例子,你们就能看明白了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

1.先创建两个接口,代表不同的验证组文章源自JAVA秀-https://www.javaxiu.com/36698.html

public interface AddPersonGroup {}public interface DeletePersonGroup {}

2.使用验证组文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

通过测试验证:文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

验证组使用下来的体验就是有点反模式的感觉,让代码的可维护性变差了!尽量不要使用!文章源自JAVA秀-https://www.javaxiu.com/36698.html

常用校验注解总结

JSR303 定义了 Bean Validation(校验)的标准 validation-api,并没有提供实现。Hibernate Validation是对这个规范/规范的实现 hibernate-validator,并且增加了 @Email@Length@Range 等注解。Spring Validation 底层依赖的就是Hibernate Validation文章源自JAVA秀-https://www.javaxiu.com/36698.html

JSR 提供的校验注解:文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Null 被注释的元素必须为 null文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @NotNull 被注释的元素必须不为 null文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @AssertTrue 被注释的元素必须为 true文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @AssertFalse 被注释的元素必须为 false文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Size(max=, min=) 被注释的元素的大小必须在指定的范围内文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Past 被注释的元素必须是一个过去的日期文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Future 被注释的元素必须是一个将来的日期文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式文章源自JAVA秀-https://www.javaxiu.com/36698.html

Hibernate Validator 提供的校验注解文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @NotBlank(message =) 验证字符串非 null,且长度必须大于 0文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Email 被注释的元素必须是电子邮箱地址文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @NotEmpty 被注释的字符串的必须非空文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Range(min=,max=,message=) 被注释的元素必须在合适的范围内文章源自JAVA秀-https://www.javaxiu.com/36698.html

拓展

经常有小伙伴问到:“@NotNull@Column(nullable = false) 两者有什么区别?”文章源自JAVA秀-https://www.javaxiu.com/36698.html

我这里简单回答一下:文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @NotNull是 JSR 303 Bean 验证批注,它与数据库约束本身无关。文章源自JAVA秀-https://www.javaxiu.com/36698.html

  • @Column(nullable = false) : 是 JPA 声明列为非空的方法。文章源自JAVA秀-https://www.javaxiu.com/36698.html

总结来说就是即前者用于验证,而后者则用于指示数据库创建表的时候对表的约束。文章源自JAVA秀-https://www.javaxiu.com/36698.html

-End-

文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

程序汪8万接的共享口罩项目,开发周期1个月文章源自JAVA秀-https://www.javaxiu.com/36698.html

文章源自JAVA秀-https://www.javaxiu.com/36698.html

文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

当一名程序员喝醉之后......文章源自JAVA秀-https://www.javaxiu.com/36698.html

文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

大厂里的外包员工:暂住甲方当丙方的日子文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了! 可乐记得加冰,爱我就要置顶 一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!素质三连biubiubiu~一坨一坨的 if/else 参数校验,终于被 SpringBoot 参数校验组件整干净了!文章源自JAVA秀-https://www.javaxiu.com/36698.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定