# SpringMVC中@Valid与@Validated的区别是什么 ## 目录 - [引言](#引言) - [基本概念](#基本概念) - [@Valid注解](#valid注解) - [@Validated注解](#validated注解) - [核心区别对比](#核心区别对比) - [1. 所属规范与来源](#1-所属规范与来源) - [2. 分组校验支持](#2-分组校验支持) - [3. 应用范围](#3-应用范围) - [4. 嵌套验证行为](#4-嵌套验证行为) - [5. 异常处理机制](#5-异常处理机制) - [使用场景分析](#使用场景分析) - [@Valid适用场景](#valid适用场景) - [@Validated适用场景](#validated适用场景) - [代码示例对比](#代码示例对比) - [基础校验示例](#基础校验示例) - [分组校验示例](#分组校验示例) - [方法参数校验示例](#方法参数校验示例) - [常见问题与解决方案](#常见问题与解决方案) - [总结](#总结) ## 引言 在SpringMVC应用开发中,参数校验是保证数据有效性的重要环节。`@Valid`和`@Validated`作为常用的校验注解,虽然功能相似,但在实际使用中存在关键差异。本文将深入剖析两者的区别,并通过实际代码示例展示它们的典型应用场景。 ## 基本概念 ### @Valid注解 - **所属规范**:JSR-303/JSR-380(Java标准验证规范) - **包路径**:`javax.validation.Valid` - **核心功能**: - 触发Bean Validation标准校验流程 - 支持级联验证(嵌套对象校验) - 默认不支持校验分组 ```java public class User { @NotNull private String username; @Valid // 级联验证Address对象 private Address address; }
org.springframework.validation.annotation.Validated
@Validated // 类级别声明 public class UserService { public void createUser(@Validated(UserGroup.Create.class) User user) { // 方法参数校验 } }
特性 | @Valid | @Validated |
---|---|---|
规范标准 | JSR-303/JSR-380 | Spring框架扩展 |
是否支持Java标准 | 是 | 否 |
是否支持Spring扩展 | 需配合Spring使用 | 原生支持Spring特性 |
@Data public class User { @NotNull(groups = UpdateGroup.class) private Long id; }
@PostMapping(”/update”) public void update(@Validated(UpdateGroup.class) User user) { // 仅校验id字段 }
- **@Valid**:无法直接支持分组,需通过其他方式实现 ### 3. 应用范围 | 应用场景 | @Valid | @Validated | |------------------|--------|------------| | 方法参数校验 | 不支持 | 支持 | | 类级别声明 | 不支持 | 支持 | | 字段级联校验 | 支持 | 支持 | | 单独使用 | 需要Validator | 可直接使用 | ### 4. 嵌套验证行为 - **@Valid**:必须显式声明才能触发嵌套验证 ```java public class Order { @Valid // 必须添加 private List<OrderItem> items; }
@Valid
使用MethodArgumentNotValidException
(Spring MVC场景)ConstraintViolationException
@Validated({DefaultGroup.class, AdvancedGroup.class})
@Service @Validated public class PaymentService { public void process(@Valid PaymentRequest request) {...} }
// 使用@Valid @PostMapping("/users") public ResponseEntity createUser(@RequestBody @Valid User user) { // 自动校验User对象 } // 使用@Validated(效果相同) @PostMapping("/users") public ResponseEntity createUser(@RequestBody @Validated User user) { // 基础校验无差别 }
// 定义校验分组 public interface BasicInfo {} public interface AdvancedInfo {} @Data public class User { @NotBlank(groups = BasicInfo.class) private String name; @Email(groups = AdvancedInfo.class) private String email; } // 分组校验 @PostMapping("/users/basic") public void createBasic(@RequestBody @Validated(BasicInfo.class) User user) { // 仅校验name字段 }
@Service @Validated // 必须添加类级别注解 public class OrderService { public void placeOrder( @Min(1) Long userId, @Valid Order order) { // 基本类型和对象同时校验 } }
校验不生效问题
@EnableWebMvc
spring-boot-starter-validation
分组校验失效
groups
属性正确配置@Validated
注解是否指定正确分组嵌套校验问题
@Valid
标记: @Valid private List<@Valid OrderItem> items;
自定义校验器集成
@Validated
更易与Spring自定义校验器集成对比维度 | @Valid | @Validated |
---|---|---|
标准性 | Java标准规范 | Spring特定实现 |
分组支持 | 不支持 | 完整支持 |
应用层次 | 主要用于DTO校验 | 可用于服务层方法校验 |
集成度 | 需要手动配置 | 深度Spring集成 |
推荐场景 | 简单校验、标准化项目 | 复杂业务校验、Spring Boot项目 |
最终建议: - 在纯Spring MVC控制器层,两者可互换使用 - 需要分组校验或方法参数校验时,必须使用@Validated
- 与其他JavaEE技术集成时建议使用@Valid
- 大型项目推荐组合使用:@Validated
控制分组,@Valid
处理嵌套验证 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。