springmvc中@valid与@validated的区别是什么

发布时间:2021-08-06 15:00:11 作者:Leah
来源:亿速云 阅读:290
# 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;
}

@Validated注解

@Validated // 类级别声明
public class UserService {
    
    public void createUser(@Validated(UserGroup.Create.class) User user) {
        // 方法参数校验
    }
}

核心区别对比

1. 所属规范与来源

特性 @Valid @Validated
规范标准 JSR-303/JSR-380 Spring框架扩展
是否支持Java标准
是否支持Spring扩展 需配合Spring使用 原生支持Spring特性

2. 分组校验支持

@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;
  }

5. 异常处理机制

使用场景分析

@Valid适用场景

  1. 需要符合JSR标准的校验
  2. 简单POJO校验(无分组需求)
  3. 与其他JavaEE技术栈集成时

@Validated适用场景

  1. 需要分组校验的复杂业务
    
    @Validated({DefaultGroup.class, AdvancedGroup.class})
    
  2. 服务层方法参数校验
    
    @Service
    @Validated
    public class PaymentService {
       public void process(@Valid PaymentRequest request) {...}
    }
    
  3. 动态校验规则切换
  4. Spring Boot自动配置环境

代码示例对比

基础校验示例

// 使用@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) {
        // 基本类型和对象同时校验
    }
}

常见问题与解决方案

  1. 校验不生效问题

    • 检查是否添加@EnableWebMvc
    • 确认依赖包含spring-boot-starter-validation
  2. 分组校验失效

    • 确保groups属性正确配置
    • 验证@Validated注解是否指定正确分组
  3. 嵌套校验问题

    • 对于集合类型,必须使用@Valid标记:
      
      @Valid
      private List<@Valid OrderItem> items;
      
  4. 自定义校验器集成

    • @Validated更易与Spring自定义校验器集成

总结

对比维度 @Valid @Validated
标准性 Java标准规范 Spring特定实现
分组支持 不支持 完整支持
应用层次 主要用于DTO校验 可用于服务层方法校验
集成度 需要手动配置 深度Spring集成
推荐场景 简单校验、标准化项目 复杂业务校验、Spring Boot项目

最终建议: - 在纯Spring MVC控制器层,两者可互换使用 - 需要分组校验或方法参数校验时,必须使用@Validated - 与其他JavaEE技术集成时建议使用@Valid - 大型项目推荐组合使用:@Validated控制分组,@Valid处理嵌套验证 “`

推荐阅读:
  1. spring与springmvc的区别是什么
  2. Spring @Valid和@Validated有什么区别

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springmvc @valid @validated

上一篇:sublime text3 中怎么生成方法注释

下一篇:如何解决某些HTML字符打不出来的问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》