SpringBoot接口参数校验N种实用技巧大揭秘

环境:SpringBoot2.6.12
实际的开发工作中大部分的接口都是需要进行参数有效性校验的 , 参数可能是简单的基本数据类型,也可能是对象类型 , 基本上所有接收参数的接口都是需要对这些参数进行校验的,你对这些参数是怎么校验的?接下来带你一起见识下我在实际项目中都应用过哪些校验姿势! 。该案例会详细介绍如下 7 方面的内容 。

  1. 简单参数校验
  2. 参数校验分组
  3. 单个参数校验
  4. 嵌套参数校验
  5. 自定义工具类参数校验
  6. 国际化支持
  7. AOP 验证参数统一处理
 
在正式介绍主体内容前我们还是先要了解学习一些规范 JSR303 。
JSR 是什么?JSR 是 JAVA Specification Requests 的缩写,意思是 Java 规范提案 。是指向 JCP(Java Community Process)提出新增一个标准化技术规范的正式请求 。任何人都可以提交 JSR,以向 Java 平台增添新的 API 和服务 。JSR 已成为 Java 界的一个重要标准 。JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constrAInt 的实现 , 除此之外还有一些附加的 constraint 。相关注解如下:
SpringBoot接口参数校验N种实用技巧大揭秘

文章插图
图片
在Spring中提供了SpringValidation验证框架对参数的验证机制提供了@Validated(Spring'sJSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),结合BindingResult对象可以直接获取错误信息 。在本案中这两种是等效的 , 但是也有区别,在接下来的案例中将会说明 。
1. 配置依赖<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><scope>runtime</scope></dependency></dependencies>org.aspectj 依赖是在最后我们要通过 AOP 技术来实现统一参数的校验 。
2. 参数验证
  • 简单参数校验
public class Users {@NotEmpty(message = "姓名必需填写")private String name ;@Min(value = https://www.isolves.com/it/cxkf/kj/2023-11-08/10, message = "年龄不能小于 10")private Integer age ;@Length(min = 6, max = 18, message = "邮箱介于 6 到 18 之间")private String email ;@NotEmpty(message = "电话必需填写")private String phone ;// 这里的2个接口在下面的案例中会使用到public static interface G1 {}public static interface G2 {}}这里对需要校验的字段都应用了不同的注解来约束 。接下来就是在Controller接口上添加相应的注解即可:
@ResponseBodypublic class UsersController extends BaseController {@RequestMApping(value = https://www.isolves.com/it/cxkf/kj/2023-11-08/"/valid/save1", method = RequestMethod.POST)public Object save1(@RequestBody @Validated Users user, BindingResult result) {Optional> op = valid(result) ;if (op.isPresent()) {return op.get() ;}return "success" ;}}public class BaseController {protected Optional> valid(BindingResult result) {if (result.hasErrors()) {return Optional.of(result.getAllErrors().stream().map(err -> err.getDefaultMessage()).collect(Collectors.toList())) ;}return Optional.empty() ;}}接收参数的 Users 对象前面要是用@Validated 注解,并且通过 BindingResult 来收集错误信息(可判断是否有错误信息);测试如下:
SpringBoot接口参数校验N种实用技巧大揭秘

文章插图
图片
正确情况
SpringBoot接口参数校验N种实用技巧大揭秘

文章插图
图片
  • 参数校验分组
有些时候我们这一个对象可能会应用到不同的场景,出现不同的校验规则该怎么做呢?这时候我们就可以应用分组功能,不同的应用场景指明不同的分组即可,开始撸 。注意:JSR303 是没有分组功能的 。
public class Users {@NotEmpty(message = "姓名不能为空", groups = G1.class)private String name ;@Min(value = https://www.isolves.com/it/cxkf/kj/2023-11-08/10, message = "年龄不能小于 10", groups = G1.class)@Min(value = 20, message = "年龄不能小于 20", groups = G2.class)private Integer age ;@Length(min = 6, max = 18, message = "邮箱介于 6 到 18 之间", groups = {G1.class, G2.class})private String email ;@NotEmpty(message = "电话必需填写")private String phone ;public static interface G1 {}public static interface G2 {}}


推荐阅读