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

@valid和@Validated的区别是什么?

文章目录

  • @Valid 和 @Validated 的区别
    • 核心区别总结
    • 详细对比
      • 1. 分组校验(最核心的区别)
      • 2. 嵌套校验
      • 3. 方法级别校验
      • 4. 使用位置
    • 实际应用实例
      • 场景1:保存和更新用不同规则
      • 场景2:嵌套对象校验
      • 场景3:Service 层参数校验
    • 常见校验注解
    • 最佳实践建议

@Valid 和 @Validated 的区别

核心区别总结

特性@Valid@Validated
所属框架Java标准 (JSR-303/JSR-380)Spring Framework
分组校验❌ 不支持✅ 支持
嵌套校验✅ 支持❌ 不支持
用在类上❌ 不可以✅ 可以(声明组)
用在方法参数✅ 可以✅ 可以
用在方法返回值❌ 不支持✅ 支持

详细对比

1. 分组校验(最核心的区别)

@Validated 支持分组,可以根据不同场景使用不同的校验规则:

// 定义分组接口publicinterfaceCreateGroup{}publicinterfaceUpdateGroup{}// 实体类publicclassDriverCertDTO{@NotNull(message="ID不能为空",groups={UpdateGroup.class})privateLongid;@NotBlank(message="驾驶证号不能为空",groups={CreateGroup.class,UpdateGroup.class})privateStringdriverLicenseNo;@NotNull(message="用户ID不能为空",groups={CreateGroup.class})privateLonguserId;}// Controller 使用分组@PostMapping("/create")publicResultcreate(@Validated(CreateGroup.class)@RequestBodyDriverCertDTOdto){// 只校验 CreateGroup 组的字段}@PutMapping("/update")publicResultupdate(@Validated(UpdateGroup.class)@RequestBodyDriverCertDTOdto){// 只校验 UpdateGroup 组的字段,id 不能为空}

2. 嵌套校验

@Valid 支持嵌套对象校验

publicclassDriverCertDTO{@Valid// 必须加 @Valid 才会校验嵌套对象privateUserDTOuser;// UserDTO 内部的校验注解会生效@Valid// 集合内对象校验privateList<@ValidVehicleDTO>vehicles;}publicclassUserDTO{@NotBlank(message="姓名不能为空")privateStringname;@Pattern(regexp="^1[3-9]\\d{9}$")privateStringphone;}

@Validated 不支持嵌套校验:

publicclassDriverCertDTO{@Validated// 无效,不会校验 UserDTO 内部字段privateUserDTOuser;}

3. 方法级别校验

@Validated 可以用在类上,开启方法参数和返回值的校验:

@Validated// 开启方法级别校验@ServicepublicclassDriverCertService{// 方法参数校验publicvoidcreate(@NotNull(message="DTO不能为空")DriverCertDTOdto){// 业务逻辑}// 返回值校验@NotNull(message="返回值不能为null")publicDriverCertDTOgetById(Longid){returndriverCertMapper.selectById(id);}}

@Valid 不能用在类上。

4. 使用位置

使用位置@Valid@Validated
Controller 参数
Service 方法参数
实体类字段(嵌套)
Controller 类
Service 类

实际应用实例

场景1:保存和更新用不同规则

// DTOpublicclassDriverCertRequest{@Null(groups={CreateGroup.class})@NotNull(groups={UpdateGroup.class})privateLongid;@NotBlank(groups={CreateGroup.class,UpdateGroup.class})privateStringdriverLicenseNo;@Null(groups={CreateGroup.class})@NotNull(groups={UpdateGroup.class})privateStringdriverStatus;}// Controller@RestControllerpublicclassDriverCertController{@PostMapping("/driver")publicResultcreate(@Validated(CreateGroup.class)@RequestBodyDriverCertRequestrequest){// 创建时 id 必须为 null,driverStatus 必须为 null}@PutMapping("/driver/{id}")publicResultupdate(@Validated(UpdateGroup.class)@RequestBodyDriverCertRequestrequest){// 更新时 id 和 driverStatus 不能为 null}}

场景2:嵌套对象校验

// 驾驶员信息包含用户信息和车辆列表publicclassDriverCertVO{@Valid// 必须用 @Valid,不能用 @ValidatedprivateUserInfouserInfo;@Valid// 嵌套集合校验privateList<@ValidVehicleInfo>vehicles;}@PostMapping("/driver/batch")publicResultbatchCreate(@Valid@RequestBodyDriverCertVOvo){// userInfo 和 vehicles 内部的校验都会执行}

场景3:Service 层参数校验

@Validated@ServicepublicclassDriverCertService{// 普通参数校验publicvoidupdateStatus(@NotNull(message="ID不能为空")Longid,@NotBlank(message="状态不能为空")Stringstatus){// 业务逻辑}// 对象参数校验publicvoidsave(@Validated(CreateGroup.class)DriverCertDTOdto){// 业务逻辑}}

常见校验注解

// 空值校验@NotNull// 不能为 null@NotBlank// 不能为 null、空字符串、纯空格@NotEmpty// 不能为 null、空集合/数组/字符串// 数值校验@Min(1)// 最小值@Max(100)// 最大值@DecimalMin("0.1")@DecimalMax("99.99")@Positive// 正数@Negative// 负数// 其他校验@Size(min=1,max=10)// 长度/大小@Pattern(regexp="...")// 正则@Email// 邮箱格式@Past// 过去时间@Future// 未来时间

最佳实践建议

  1. 一般场景用 @Valid 即可,简单明了

  2. 需要分组校验时用 @Validated(如创建/更新共用 DTO)

  3. 嵌套对象校验必须用 @Valid

  4. Service 层参数校验用 @Validated(需要加在类上)

  5. 可以组合使用:Controller 用 @Validated 做分组,内部嵌套用 @Valid

// 组合使用示例publicclassOrderDTO{@Valid// 嵌套校验privateUserDTOuser;@Valid// 集合嵌套校验privateList<@ValidItemDTO>items;}@PostMapping("/order")publicResultcreate(@Validated(CreateGroup.class)@RequestBodyOrderDTOorder){// 外层用 @Validated 分组,内层用 @Valid 嵌套}
http://www.jsqmd.com/news/800718/

相关文章:

  • [BUUCTF]内涵的软件
  • 基于MCP协议的AI智能体如何自动化CRM数据管理与广告投放
  • VLA技术研究
  • Perplexity接入ScienceDirect文献库全链路解析(2024科研人必抢的AI学术入口)
  • 前端周报:Remix 3、Node 26 与 Chrome 148
  • Linux 性能分析工具 sar 历史数据缺失如何配置 sysstat 服务?
  • 别再死记硬背公式了!用Python动画可视化tf.nn.depth_to_space的完整数据搬运过程
  • 基于语义的会话搜索:从向量化到工程实践
  • 硬核干货!从RAG到多模态RAG:核心知识、架构Checklist与避坑实战指南
  • Unity手游资源逆向:从APK到Assembly-CSharp的提取与解析
  • 别再傻傻用matlab求逆了!用追赶法高效求解三对角矩阵(附MATLAB代码)
  • Terafab芯片项目正式启动;三星加速P5工厂建设1c纳米工艺支撑HBM4量产;香港科技大学研发的220磅月球建筑机器人正式亮相
  • 【2025最新】基于SpringBoot+Vue的夕阳红公寓管理系统管理系统源码+MyBatis+MySQL
  • 2026年最值得做的AI副业:普通人如何利用AI建立持续收入
  • WASM学习笔记
  • Verilog与SystemVerilog在Cycle Model Compiler中的核心支持解析
  • 没有工作经验,他半月拿下算法岗位
  • SQE是什么鬼?一个在世界500强做供应商质量的人,说说这个容易被误解的岗位
  • 通用AGI终极范式:从多模态感知到意识涌现的统一理论(世毫九实验室原创研究)
  • 从计算机小白到AI大模型工程师:我的3个月学习路线(收藏版)
  • CADMATIC许可排队严重?不想买新许可,共享浮动许可池
  • League Akari:基于LCU API的英雄联盟客户端模块化架构深度解析
  • 免费开源AI软件.桌面单机版,可移动的AI知识库,察元 AI桌面版:本地离线知识库的第一份 PDF 引用气泡是怎么连回原文的
  • 企业级中小企业人事管理系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
  • PyVideoTrans:5步实现视频翻译与AI配音,开源工具让多语言内容创作更简单
  • 选NCHW还是NHWC?从TensorFlow、PyTorch到实际模型,聊聊数据格式对训练速度的真实影响
  • 大麦抢票神器哪个最好用?
  • 概率论:二维随机变量
  • 新冠病毒密接者跟踪系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
  • 构建高效协作沙盒:从Git工作流到CI/CD的团队研发实践