@Validated与@Valid的正确使用姿势
验证代码
@Validated
@RestController
public class A {@PostMappingpublic void test(@Min(value = 1) Integer count) {} // 校验规则生效
}@RestController
public class A {@PostMappingpublic void test(@Validated @Min(value = 1) Integer count) {} // 校验规则不生效
}@RestController
public class A {@PostMappingpublic void test(@Valid @Min(value = 1) Integer count) {} // 校验规则不生效
}@Data
public class User {@NotBlankprivate String name;@Valid@NotNullprivate Address address;
}@Data
public class Address {@NotBlankprivate String city;
}@Validated
@RestController
public class A {@PostMappingpublic void test(User user) {} // 校验规则不生效
}@Validated
@RestController
public class A {@PostMappingpublic void test(@NotNull User user) {} // 校验规则不生效
}@RestController
public class A {@PostMappingpublic void test(@Validated User user) {} // 校验规则生效
}@RestController
public class A {@PostMappingpublic void test(@Valid User user) {} // 校验规则生效
}
Spring参数校验:@Validated与@Valid的正确使用姿势
在Spring Boot开发中,参数校验是保证接口健壮性的重要手段。然而,许多开发者在使用@Validated
和@Valid
时容易混淆,导致校验规则未按预期生效。本文将通过代码示例解析不同场景下校验规则生效的原理,并总结最佳实践。
1. 基本类型参数的校验
场景1:类级别使用@Validated
@Validated // 关键注解
@RestController
public class A {@PostMappingpublic void test(@Min(value = 1) Integer count) {} // 校验生效
}
- 生效原因:
@Validated
注解在类级别启用方法参数校验。此时,直接作用在参数上的约束注解(如@Min
)会被Spring处理。
场景2:参数级别使用@Validated或@Valid
@RestController
public class A {@PostMappingpublic void test(@Validated @Min(1) Integer count) {} // 不生效
}@RestController
public class A {@PostMappingpublic void test(@Valid @Min(1) Integer count) {} // 不生效
}
- 不生效原因:
基本类型的参数校验需要类级别的@Validated
支持。单独在参数上使用@Validated
或@Valid
无法触发校验。
2. 对象类型参数的校验
场景1:未标记@Valid或@Validated
@Validated
@RestController
public class A {@PostMappingpublic void test(User user) {} // 不生效
}
- 不生效原因:
虽然类上有@Validated
,但未在参数上添加@Valid
或@Validated
,Spring不会自动校验对象内部的字段约束。
场景2:参数级别使用@Valid或@Validated
@RestController
public class A {@PostMappingpublic void test(@Validated User user) {} // 生效
}@RestController
public class A {@PostMappingpublic void test(@Valid User user) {} // 生效
}
- 生效原因:
对于对象类型的参数,Spring MVC会自动处理参数上的@Valid
或@Validated
,无需类级别注解。这会递归校验对象内部的所有字段约束。
3. 嵌套对象的级联校验
实体类定义:
@Data
public class User {@NotBlankprivate String name;@Valid // 启用嵌套校验@NotNullprivate Address address;
}@Data
public class Address {@NotBlankprivate String city;
}
- 关键点:
在嵌套对象字段(如address
)上添加@Valid
,Spring会递归校验其内部约束。
4. 常见误区总结
场景 | 是否生效 | 原因 |
---|---|---|
基本类型 + 类级别@Validated | ✅ | 类级别启用校验,参数约束生效。 |
基本类型 + 参数级别@Valid/@Validated | ❌ | 缺少类级别支持,无法触发校验。 |
对象类型 + 参数级别@Valid/@Validated | ✅ | Spring MVC自动处理对象参数校验。 |
对象类型 + 无参数注解 | ❌ | 需要显式标记@Valid 或@Validated 以触发校验。 |
5. 最佳实践
-
基本类型参数校验:
在类上添加@Validated
,参数直接使用约束注解(如@Min
)。 -
对象类型参数校验:
在参数上使用@Valid
或@Validated
,无需类级别注解。 -
嵌套校验:
在嵌套对象的字段上添加@Valid
以触发级联校验。
通过合理使用@Validated
和@Valid
,可以确保参数校验逻辑清晰且高效。理解其背后的机制,能够避免常见的“校验不生效”问题,提升代码质量。