当前位置: 首页 > article >正文

Spring validation 分组校验用法

前言

在使用 Java Bean Validation 进行参数校验的时候,很多场景下的一个Req实体都是同时满足多个业务,但是可能在不同的业务场景下,参数校验有细微的差别。例如在新增用户和编辑用户的场景下,UserReq实体相同,但是编辑的时候用户ID是必填的。如果想要新增用户和编辑用户共用一个UserReq实体,就只能在id属性上去掉@NotNull注解,在编辑方法上手动判断,这样实际上比较麻烦,也不够优雅。

public class UserReq {
  private Long id;
  @NotEmpty(message="name 不能为空")
  private String name;
  @NotNull(message="age 不能为空")
  private int age;
  ...
}
public class UserController{
  public R create(@RequestBody @Valid UserReq userReq){
    ...
  }
  public R edit(@RequestBody @Valid UserReq userReq){
    // 手动判断id
    if(userReq.getId() == null){
      throw new ServiceException(...)
    }
    ...
  }
}

如果能给id字段上打一个记号,标识出id字段只需要编辑时校验,新增的时候忽视掉就好了。

实现

实际上,@NotEmpty、@NotNull … 注解上有一个属性,叫做groups,用于指定一个验证分组。它允许你对同一个对象应用不同的验证规则,具体规则可以根据上下文的不同而有所不同。

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(NotNull.List.class)
@Documented
@Constraint(
    validatedBy = {}
)
public @interface NotNull {
    String message() default "{javax.validation.constraints.NotNull.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface List {
        NotNull[] value();
    }
}

于是我们可以定义不同的验证分组接口,用于标识不同的验证场景。例如:

public interface ValidGroup {

    interface InsertGroup {

    }
    interface UpdateGroup {

    }

    interface DeleteGroup {

    }
}

然后在Req实体的属性上标注出场景

public class UserReq {
  @NotNull(message="id不能为空", groups = {UpdateGroup.class})
  private Long id;
  @NotEmpty(message="name不能为空", groups = {InsertGroup.class, UpdateGroup.class})
  private String name;
  @NotNull(message="age不能为空", groups = {InsertGroup.class, UpdateGroup.class})
  private int age;
  ...
}

然后在Controller接口方法上制定验证的分组规则

public class UserController{
  public R create(@RequestBody @Validated(ValidGroup.InsertGroup.class) UserReq userReq){
    ...
  }
  public R edit(@RequestBody @Validated(ValidGroup.UpdateGroup.class) UserReq userReq){
    ...
  }
}

这样就实现参数的优雅校验了。


http://www.kler.cn/a/404825.html

相关文章:

  • vue3:使用插件递归组件
  • AI一键生成原创花卉印花图案——创新与效率的结合
  • 内存(RAM)详细介绍
  • Sourcetree登录GitLab账号
  • Python 绘图工具详解:使用 Matplotlib、Seaborn 和 Pyecharts 绘制散点图
  • 单细胞转录组学在植物系统和合成生物学中的应用进展-文献精读83
  • WPF如何全局应用黑白主题效果
  • Java多线程编程详解
  • 亿咖通科技应邀出席微软汽车行业智享会,分享ECARX AutoGPT全新实践
  • GitLab|GitLab报错:PG::ConnectionBad: could not connect to server...
  • springboot基于微信小程序的食堂预约点餐系统
  • 使用线程局部存储解决ffmpeg中多实例调用下自定义日志回调问题
  • 力扣 LeetCode 110. 平衡二叉树(Day8:二叉树)
  • 在windows电脑上安装docker服务
  • 大模型试用-t5-base
  • 深度学习的分布式训练与集合通信(一)
  • 调试QRNet遇到的问题
  • 基于Windows系统用C++做一个点名工具
  • 算法学习笔记(六):二叉树一创建、插入、删除、BFS
  • 测试工程师如何在面试中脱颖而出
  • 【软件架构】软件的十二种架构简介
  • 操作系统安全入门:渗透测试基础与实践
  • 存算分离的过去、现在和未来
  • 【Oracle篇】SQL性能优化实战案例(从15秒优化到0.08秒)(第七篇,总共七篇)
  • 前端反向代理的配置和實現
  • 深入解析MySQL中的事务处理