浅析JSR303数据校验

一、后端校验技术

  JSR303技术,JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint,在springboot中使用也比较简便。

1、给需要校验的字段添加校验注解

  在javax.validation.constraints包下有许多的注解:

  Hibernate Validator 附加的 constraint

  常用的校验注解补充:

@NotBlank 检查约束字符串是不是Null,还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格。

@NotEmpty 检查约束元素是否为NULL或者是EMPTY

@Length 被检查的字符串长度是否在指定的范围内

@CreditCardNumber信用卡验证

@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。

@URL 验证是否是一个url地址

  注意:一个字段可以标注多个校验注解。

2、给需要检验的方法标准@Valid

  如果只标注了注解字段,不启用@valid的是不生效的。

3、捕捉校验异常,返回提示信息

  一般其报错只是在报错异常里面有这个报错,那如果想让用户看到,也就是返回如下的json数据,该如何做呢?

{
  "operateMessage": "年龄太小",
  "success": false
}

  这个需要,自定义统一返回类、自定义统一异常捕获,一般项目里也都会有。只需在自定义异常捕获类里加上对MethodArgumentNotValidException异常的捕获即可

复制代码
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public OperationInfo methodArgumentNotValidException(HttpServletRequest request, HttpServletResponse response, MethodArgumentNotValidException ex) {
  log.error("参数违反约束, {}, {}, {}", request.getRequestURI(), ex.getMessage(), LogUtil.getStack(ex));
  // 其中OperationInfo是我们项目自定义的统一返回类
  return OperationInfo.failure(ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
}
复制代码

二、分组校验(多场景的复杂校验)

  对于不同的操作,字段校验的规则和数量可能是不同的,所以我们将校验规则分组,对于不同的操作进行不同的校验组,使用groups属性。

(1)想要使用分组校验功能,根据文档我们首先编写不同的校验组接口,只编写空接口,用来表示就可以了:

复制代码
//新增分组
public interface AddGroup{
​
}
//修改分组
public interface UpdateGroup{
​
}
复制代码

(2)编写好分组接口,对于不同的检验规则,标注不同的分组标识

复制代码
@NotNull ( message ="修改必须指定id",groups = {UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {AddGroup.class})
@TableId
private Long Id;
​
@NotBlank(message="名称必须提交",groups={AddGroup.class,UpdateGroup.class})
private String name;
复制代码

(3)在controller方法上标注不同的分组校验,使用@Validated注解

复制代码
 //保存
 @RequestMapping("/save")
 //@RequiresPermissions("product:brand:save")
 public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand){
 brandService.save(brand);
 return R.ok();
 }
复制代码

  @Validated({AddGroup.class}):启用不同的分组校验规则。

  注意:在使用分组校验的情况下,对于没有标注分组的校验规则,默认是不生效的,只有标注了分组的校验规则才会生效。

三、其他相关

1、导入依赖:如果 spring-boot 小于 2.3.x,会自动导入依赖;如果大于 2.3.x,则需要手动导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.5.4</version>
</dependency>

2、级联校验

  通常使用@Validated用在方法上, 级联验证配合使用@Valid使用在属性上

【@Validated】:可用在类型、方法和方法参数上,不能用在成员属性(字段)上

【@Valid】:可用在方法、构造函数、方法参数和成员属性(字段)上

复制代码
public OperationInfo save(@RequestBody @Validated User user) {
  return userService.save(esKnowledge);
}

@Data
public class User {
  @Valid
  private School school;
}

// 级联实体
@Data
public class School {
  @NotBlank(message = "学校名不能为空")
  private String name;
}
复制代码

3、集合校验

复制代码
// 验证实体,级联实体跟上面一样
@Data
public class User {
  @Valid
  @NotEmpty(message = "列表不能为空")
  private List<@NotNull(message = "School不能为空") School> schools;
}
复制代码

  当School的name为null时,会报错:does not have a corresponding accessor for Spring data binding,在统一异常捕获中加入如下代码即可

@InitBinder
private void activateDirectFieldAccess(DataBinder dataBinder) {
  dataBinder.initDirectFieldAccess();
}

 

posted @   古兰精  阅读(566)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2018-06-01 ElementUI日期选择器时间选择范围限制
2018-06-01 Vue使用中遇到问题汇总(三)
点击右上角即可分享
微信分享提示