Validation验证
Validation
Jakarta Bean Validation
Jakarta Bean Validation 提供了一套常见的内置约束注解,涵盖了不同类型的数据验证需求。以下是这些内置约束注解的详细解释,包括其功能、适用场景和使用示例。
1. @NotNull
- 功能: 验证字段不能为
null
,但可以是空字符串、空集合等。 - 适用类型: 任何引用类型(如对象、集合、数组等),不适用于原始类型(
int
,boolean
等)。 - 示例:
如果@NotNull(message = "用户名不能为空") private String username;
username
为null
,验证将失败。
2. @NotEmpty
- 功能: 验证集合、数组或字符串不能为
null
且不能为空。 - 适用类型: 字符串、集合、数组。
- 示例:
如果@NotEmpty(message = "用户名不能为空") private String username; @NotEmpty(message = "角色列表不能为空") private List<String> roles;
username
是空字符串""
或roles
是空集合[]
,验证将失败。
3. @NotBlank
- 功能: 验证字符串不能为
null
,且去除空格后必须至少包含一个非空字符。 - 适用类型: 字符串。
- 示例:
如果@NotBlank(message = "用户名不能为空") private String username;
username
是null
、空字符串""
或只包含空格" "
,验证将失败。
4. @Size
- 功能: 验证字符串、数组、集合或 Map 的长度或大小在指定范围内。
- 适用类型: 字符串、数组、集合、Map。
- 示例:
验证@Size(min = 5, max = 15, message = "用户名长度必须在5到15个字符之间") private String username; @Size(min = 1, message = "至少要有一个角色") private List<String> roles;
username
的长度必须在 5 到 15 个字符之间,roles
至少要包含一个元素。
5. @Min 和 @Max
- 功能: 验证数值必须大于等于
@Min
指定的值,或小于等于@Max
指定的值。 - 适用类型: 数值类型(如
int
,long
,double
)。 - 示例:
验证@Min(value = 18, message = "年龄不能小于18岁") @Max(value = 65, message = "年龄不能大于65岁") private int age;
age
必须在 18 到 65 之间。
6. @Pattern
- 功能: 验证字符串是否符合指定的正则表达式模式。
- 适用类型: 字符串。
- 示例:
验证@Pattern(regexp = "^[A-Za-z0-9]+$", message = "用户名只能包含字母和数字") private String username;
username
只能包含字母和数字。
7. @Email
- 功能: 验证字符串是否是一个合法的电子邮件地址。
- 适用类型: 字符串。
- 示例:
验证@Email(message = "电子邮件格式不正确") private String email;
email
是否符合电子邮件格式。
8. @Positive 和 @PositiveOrZero
- 功能:
@Positive
验证数值必须为正数;@PositiveOrZero
验证数值必须为正数或零。 - 适用类型: 数值类型。
- 示例:
@Positive(message = "库存数量必须为正数") private int stock; @PositiveOrZero(message = "库存不能为负数") private int stock;
9. @Negative 和 @NegativeOrZero
- 功能:
@Negative
验证数值必须为负数;@NegativeOrZero
验证数值必须为负数或零。 - 适用类型: 数值类型。
- 示例:
@Negative(message = "余额必须为负数") private BigDecimal balance; @NegativeOrZero(message = "余额必须为零或负数") private BigDecimal balance;
10. @Future 和 @FutureOrPresent
- 功能:
@Future
验证日期必须是将来的时间;@FutureOrPresent
验证日期必须是将来或当前时间。 - 适用类型: 日期类型(如
java.util.Date
,java.time.LocalDateTime
,java.time.LocalDate
)。 - 示例:
如果@Future(message = "预定日期必须是未来的时间") private LocalDate bookingDate;
bookingDate
是当前时间或过去的时间,验证将失败。
11. @Past 和 @PastOrPresent
- 功能:
@Past
验证日期必须是过去的时间;@PastOrPresent
验证日期必须是过去或当前时间。 - 适用类型: 日期类型。
- 示例:
@Past(message = "出生日期必须是过去的时间") private LocalDate birthDate;
12. @AssertTrue 和 @AssertFalse
- 功能:
@AssertTrue
验证字段的值必须为true
;@AssertFalse
验证字段的值必须为false
。 - 适用类型: 布尔类型。
- 示例:
@AssertTrue(message = "必须同意用户协议") private boolean agreed; @AssertFalse(message = "这个选项不能为真") private boolean someFlag;
13. @Digits
- 功能: 验证数值的整数部分和小数部分的位数。
- 适用类型: 数值类型。
- 示例:
@Digits(integer = 5, fraction = 2, message = "金额格式不正确,整数部分最多5位,小数部分最多2位") private BigDecimal amount;
14. @DecimalMin 和 @DecimalMax
- 功能: 验证数值是否大于等于(
@DecimalMin
)或小于等于(@DecimalMax
)指定的值,支持小数。 - 适用类型: 数值类型。
- 示例:
@DecimalMin(value = "0.01", message = "金额不能小于0.01") private BigDecimal price; @DecimalMax(value = "10000.00", message = "金额不能超过10000.00") private BigDecimal price;
15. @CreditCardNumber
- 功能: 验证是否是合法的信用卡号(基于 Luhn 校验算法)。
- 适用类型: 字符串。
- 示例:
@CreditCardNumber(message = "信用卡号不合法") private String creditCardNumber;
16. @Range(来自 Hibernate Validator)
- 功能: 验证数值是否在指定的范围内(类似于
@Min
和@Max
)。 - 适用类型: 数值类型。
- 示例:
@Range(min = 1, max = 100, message = "值必须在1到100之间") private int number;
17. @URL(来自 Hibernate Validator)
- 功能: 验证字符串是否是合法的 URL。
- 适用类型: 字符串。
- 示例:
@URL(message = "URL格式不正确") private String website;
18. @SafeHtml(来自 Hibernate Validator)
- 功能: 验证字符串是否仅包含安全的 HTML 内容,防止 XSS 攻击。
- 适用类型: 字符串。
- 示例:
@SafeHtml(message = "HTML内容不安全") private String htmlContent;
19. @UniqueElements(来自 Hibernate Validator)
- 功能: 验证集合中的元素是否唯一。
- 适用类型: 集合类型。
- 示例:
@UniqueElements(message = "集合中的元素必须唯一") private List<String> tags;
Hibernate Validator
org.hibernate.validator
是 Hibernate Validator 的核心包,它是 Jakarta Bean Validation(JSR 380)的参考实现。除了 Jakarta Bean Validation 标准提供的内置约束注解外,Hibernate Validator 还扩展了许多额外的注解,用于更复杂或特定场景的数据校验。以下是 Hibernate Validator 提供的全部内置约束注解的详细讲解。
1. @Length
- 功能: 验证字符串的长度是否在指定范围内。
- 适用类型: 字符串。
- 示例:
如果@Length(min = 5, max = 15, message = "用户名长度必须在5到15个字符之间") private String username;
username
的长度不在 5 到 15 个字符之间,验证将失败。
2. @Range
- 功能: 验证数值是否在指定的范围内。
- 适用类型: 数值类型(如
int
,long
,double
)。 - 示例:
验证@Range(min = 1, max = 100, message = "值必须在1到100之间") private int value;
value
是否在 1 到 100 之间。
3. @CreditCardNumber
- 功能: 验证字符串是否是有效的信用卡号(基于 Luhn 校验算法)。
- 适用类型: 字符串。
- 示例:
验证信用卡号是否合法。@CreditCardNumber(message = "信用卡号不合法") private String creditCardNumber;
4. @URL
- 功能: 验证字符串是否是合法的 URL。
- 适用类型: 字符串。
- 示例:
验证@URL(message = "URL格式不正确") private String website;
website
是否是合法的 URL。
5. @EAN
- 功能: 验证字符串是否是有效的 EAN(国际商品编码)。支持 EAN-8 和 EAN-13。
- 适用类型: 字符串。
- 示例:
验证@EAN(type = EAN.Type.EAN13, message = "必须是有效的EAN-13编码") private String productCode;
productCode
是否为有效的 EAN-13 代码。
6. @ISBN
- 功能: 验证字符串是否是有效的 ISBN(国际标准书号)。支持 ISBN-10 和 ISBN-13。
- 适用类型: 字符串。
- 示例:
验证@ISBN(type = ISBN.Type.ISBN13, message = "必须是有效的ISBN-13编码") private String bookCode;
bookCode
是否为有效的 ISBN-13。
7. @SafeHtml
- 功能: 验证字符串是否仅包含安全的 HTML 内容。它用于防止 XSS(跨站脚本)攻击。
- 适用类型: 字符串。
- 示例:
验证@SafeHtml(message = "HTML内容不安全") private String description;
description
是否仅包含安全的 HTML 标签。
8. @UniqueElements
- 功能: 验证集合或数组中的元素是否唯一。
- 适用类型: 集合、数组。
- 示例:
验证@UniqueElements(message = "集合中的元素必须唯一") private List<String> tags;
tags
列表中的元素是否唯一。
9. @ScriptAssert
- 功能: 通过脚本表达式进行自定义校验,支持 Groovy、JavaScript 等语言的脚本校验。
- 适用类型: 类级别的约束注解,用于校验整个对象。
- 示例:
验证@ScriptAssert(lang = "groovy", script = "_this.startDate.before(_this.endDate)", message = "开始日期必须早于结束日期") public class Event { private Date startDate; private Date endDate; }
startDate
必须早于endDate
。
10. @ParameterScriptAssert
- 功能: 类似于
@ScriptAssert
,但用于方法参数的校验。 - 适用类型: 方法级别的约束注解。
- 示例:
验证传递给@ParameterScriptAssert(lang = "groovy", script = "arg1 != null && arg1.size() > 0", message = "参数不能为空") public void process(@Valid List<String> data) { // 方法逻辑 }
data
的参数不能为空且不为空列表。
11. @Email(Hibernate 扩展)
- 功能: 验证字符串是否是合法的电子邮件地址。相比于 Jakarta 标准的
@Email
注解,Hibernate 的@Email
支持更多高级配置,如允许不包含顶级域名的电子邮件地址。 - 适用类型: 字符串。
- 示例:
@Email(message = "邮箱格式不正确") private String email;
12. @Mod10Check 和 @Mod11Check
- 功能: 验证字符串是否符合 Mod10 或 Mod11 校验算法,通常用于校验条形码或身份证号等。
- 适用类型: 字符串。
- 示例:
@Mod10Check(message = "条形码不合法") private String barcode;
13. @CNPJ 和 @CPF
- 功能: 验证巴西的企业识别号(CNPJ)和个人识别号(CPF)是否合法。
- 适用类型: 字符串。
- 示例:
@CPF(message = "CPF号不合法") private String cpf; @CNPJ(message = "CNPJ号不合法") private String cnpj;
14. @LuhnCheck
- 功能: 使用 Luhn 校验算法验证数值是否合法。Luhn 算法常用于验证信用卡号等。
- 适用类型: 字符串、数字。
- 示例:
@LuhnCheck(message = "信用卡号不合法") private String creditCardNumber;
15. @Currency
- 功能: 验证字段是否符合 ISO 4217 货币代码(例如 USD、EUR)。
- 适用类型: 字符串。
- 示例:
@Currency(value = "USD", message = "必须是有效的货币代码") private String currency;
16. @DurationMax 和 @DurationMin
- 功能: 验证
java.time.Duration
对象的时间长度是否在指定的范围内。 - 适用类型:
java.time.Duration
类型。 - 示例:
@DurationMin(hours = 1, message = "持续时间必须至少1小时") @DurationMax(days = 1, message = "持续时间不能超过1天") private Duration eventDuration;
17. @ParameterScriptAssert
- 功能: 用于方法参数的复杂自定义验证,通过脚本表达式定义校验逻辑。
- 适用类型: 方法参数。
- 示例:
@ParameterScriptAssert(lang = "groovy", script = "arg1 > arg2", message = "第一个参数必须大于第二个参数") public void validateParams(int param1, int param2) { // 逻辑 }
18. @Digits
- 功能: 验证数值的整数部分和小数部分的位数。
- 适用类型: 数值类型。
- 示例:
@Digits(integer = 5, fraction = 2, message = "金额格式不正确,整数部分最多5位,小数部分最多2位") private BigDecimal price;
Jakarta Bean Validation 和 Hibernate Validator 都支持自定义验证器,允许你根据特定的业务需求定义自定义的验证规则。自定义验证器的工作原理是通过创建一个自定义的约束注解(Constraint),并为其实现对应的验证逻辑。
Validator(验证器)
Jakarta Bean Validation 和 Hibernate Validator 都允许自定义验证器,使你可以根据业务需求实现高度定制的校验规则。
自定义验证器的场景:
- 特定业务规则:如验证用户输入的用户名格式、密码强度、特殊业务规则等。
- 跨字段验证:如验证两个字段的值是否一致(如密码与确认密码)。
- 复杂对象验证:如验证对象内的嵌套对象或列表中的元素是否满足特定条件。
- 自定义验证器通过注解、
ConstraintValidator
接口以及实体类的结合来工作,可以处理简单或复杂的验证逻辑。 - 可以在自定义注解中传递参数,使验证器更加灵活,满足不同的验证需求。
自定义验证器的步骤:
- 创建自定义注解:定义注解用于标识需要应用验证规则的字段或方法。
- 实现
ConstraintValidator
接口:编写验证逻辑。 - 将自定义注解应用到实体类:在需要的字段或方法上使用该自定义注解。
1. 创建自定义注解
首先需要定义一个自定义注解。这个注解必须使用 @Constraint
注解来指定验证器类,并且它本身可以包含验证消息、分组、以及负载类型的参数。
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 自定义注解
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyCustomValidator.class) // 绑定验证器类
public @interface MyCustomConstraint {
String message() default "自定义校验失败"; // 默认错误消息
Class<?>[] groups() default {}; // 分组
Class<? extends Payload>[] payload() default {}; // 用于附加信息的载荷
}
- @Target: 指定自定义注解的适用范围,
FIELD
表示可以应用于字段,METHOD
表示可以应用于方法,PARAMETER
表示可以应用于方法参数。 - @Retention: 表示注解的生命周期,
RUNTIME
意味着注解将在运行时有效。 - @Constraint: 指定验证器类,通过
validatedBy
属性将注解与验证逻辑类绑定。 - message: 定义校验失败时的默认错误消息。
- groups 和 payload: 这两个属性用于分组校验和自定义载荷,是 Jakarta Bean Validation 规范的要求,尽管你在大多数情况下不会使用它们。
2. 实现 ConstraintValidator
接口
在实现自定义验证逻辑时,需要创建一个实现 ConstraintValidator
接口的类。该类定义如何对目标对象进行验证。
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class MyCustomValidator implements ConstraintValidator<MyCustomConstraint, String> {
@Override
public void initialize(MyCustomConstraint constraintAnnotation) {
// 可以在此初始化一些逻辑,比如读取注解的参数
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 自定义校验逻辑
if (value == null || value.contains("abc")) {
return true; // 校验通过
}
return false; // 校验失败
}
}
ConstraintValidator
是一个泛型接口,接收两个参数:- 第一个参数是自定义注解的类型(
MyCustomConstraint
)。 - 第二个参数是要校验的数据类型(这里是
String
)。
- 第一个参数是自定义注解的类型(
initialize
方法允许在验证器初始化时执行一些逻辑(如从注解中读取属性值),通常用于准备工作。isValid
方法包含实际的校验逻辑,如果验证成功,返回true
,否则返回false
。
3. 在实体类中使用自定义注解
最后,将自定义注解应用于实体类中的字段、方法或参数,来验证数据。
public class User {
@MyCustomConstraint(message = "用户名必须包含 'abc'")
private String username;
// getters and setters
}
在这个例子中,username
字段将会使用自定义的验证规则进行校验:如果 username
包含字符串 "abc"
,验证通过,否则验证失败。
自定义验证器的高级用法
在自定义验证器中,你可以定义更复杂的校验逻辑,并根据需求自定义注解的行为。
1. 处理复杂数据类型
自定义验证器不仅仅可以处理简单类型(如 String
),还可以处理复杂类型(如 List
、Map
、自定义类等)。例如,可以编写一个验证器,验证列表中的每个元素是否符合某个规则。
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.List;
public class ListValidator implements ConstraintValidator<MyCustomConstraint, List<String>> {
@Override
public boolean isValid(List<String> value, ConstraintValidatorContext context) {
if (value == null || value.isEmpty()) {
return false; // 验证列表是否为空
}
// 验证列表中的每个元素
for (String element : value) {
if (element == null || !element.matches("[A-Za-z0-9]+")) {
return false;
}
}
return true;
}
}
在实体类中使用:
public class Product {
@MyCustomConstraint(message = "标签列表中必须包含有效的标签")
private List<String> tags;
// getters and setters
}
2. 使用注解的参数
自定义注解可以接收参数,并在 ConstraintValidator
中使用这些参数动态调整校验逻辑。
修改注解定义以接收参数:
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyCustomValidator.class)
public @interface MyCustomConstraint {
String message() default "自定义校验失败";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
// 自定义参数
String prefix() default "abc";
}
在验证器中使用参数:
public class MyCustomValidator implements ConstraintValidator<MyCustomConstraint, String> {
private String prefix;
@Override
public void initialize(MyCustomConstraint constraintAnnotation) {
this.prefix = constraintAnnotation.prefix(); // 从注解中读取参数
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 根据 prefix 参数进行校验
if (value != null && value.startsWith(prefix)) {
return true;
}
return false;
}
}
使用时可以指定不同的 prefix
参数:
public class User {
@MyCustomConstraint(prefix = "user", message = "用户名必须以 'user' 开头")
private String username;
// getters and setters
}
3. 组合约束
你可以组合多个约束注解,形成一个复杂的自定义校验逻辑。组合约束允许你复用现有的注解。
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
@NotNull
@Size(min = 5, max = 15)
@MyCustomConstraint
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CombinedConstraint {
String message() default "组合校验失败";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
在实体类中使用组合约束:
public class User {
@CombinedConstraint(message = "用户名校验失败")
private String username;
// getters and setters
}
分组验证(Groups)
- 分组验证(Groups) 是一种高级功能,允许在不同业务场景中应用不同的验证规则。
- 分组接口 用于标识和区分不同的验证逻辑。
- 可以通过
@GroupSequence
设定分组验证的执行顺序,以确保某些组的验证优先执行。 - Hibernate Validator 提供了扩展功能,如分组转换(Group Conversion)和对集合元素进行分组验证。
- 在 Spring 中,可以使用
@Validated
注解来指定分组验证,结合 Bean Validation 和服务层逻辑进行数据验证。
Jakarta Bean Validation 和 Hibernate Validator 的分组验证(Groups)是验证机制中一种高级功能,它允许开发者为相同的实体类字段或方法指定不同的验证规则,并根据业务需求选择性地应用这些验证规则。分组验证使得在不同场景(如创建、更新、删除等)时,能够灵活地应用不同的验证逻辑。
1. 分组验证的基本概念
在 Jakarta Bean Validation 中,所有的验证默认属于 默认组(Default
组)。如果没有指定验证组,验证器会将所有注解都视为属于 Default
组并执行。
通过分组验证,开发者可以创建多个验证组,并为每个字段定义不同组下的验证规则。这样可以根据不同的场景(如表单验证、API 调用、实体更新等)来选择性应用验证规则。
2. 如何定义和使用分组验证
a. 定义分组接口
首先,需要定义空接口来表示验证分组。通常这些接口只起标记作用,不需要任何方法。
public interface CreateGroup {}
public interface UpdateGroup {}
b. 在实体类中使用分组
通过 groups
属性为每个约束注解指定它属于哪个分组。
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
public class User {
@NotNull(message = "用户名不能为空", groups = CreateGroup.class)
@Size(min = 5, max = 20, message = "用户名长度必须在5到20个字符之间", groups = {CreateGroup.class, UpdateGroup.class})
private String username;
@NotNull(message = "密码不能为空", groups = CreateGroup.class)
@Size(min = 8, message = "密码长度至少为8个字符", groups = CreateGroup.class)
private String password;
// getters 和 setters
}
在这个例子中:
username
字段在CreateGroup
分组下需要满足非空和长度限制,而在UpdateGroup
分组下,只需要满足长度限制。password
字段只在创建用户时(CreateGroup
)需要验证,更新时不需要。
c. 验证时指定分组
不推荐,这种会增加代码的可读性
要使用分组验证,需要在调用 Validator.validate()
方法时指定分组。Jakarta Bean Validation 提供了 Validator
接口,可以手动指定需要验证的分组。
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
public class UserService {
private Validator validator;
public UserService() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
this.validator = factory.getValidator();
}
// 创建用户时使用创建分组
public void createUser(User user) {
Set<ConstraintViolation<User>> violations = validator.validate(user, CreateGroup.class);
handleViolations(violations);
}
// 更新用户时使用更新分组
public void updateUser(User user) {
Set<ConstraintViolation<User>> violations = validator.validate(user, UpdateGroup.class);
handleViolations(violations);
}
private void handleViolations(Set<ConstraintViolation<User>> violations) {
if (!violations.isEmpty()) {
for (ConstraintViolation<User> violation : violations) {
System.out.println(violation.getPropertyPath() + ": " + violation.getMessage());
}
}
}
}
在创建和更新用户时,分别调用 validate()
方法并传递不同的分组(CreateGroup
和 UpdateGroup
),以便应用不同的验证规则。
3. 组合验证分组
a. 同时应用多个分组
如果你想在一次验证中应用多个分组,可以在 validate()
方法中传递多个分组类。系统会同时执行这些组中的所有验证规则。
Set<ConstraintViolation<User>> violations = validator.validate(user, CreateGroup.class, UpdateGroup.class);
b. 通过 @GroupSequence 设定验证顺序
在某些情况下,你可能希望按特定顺序执行不同的验证组。例如,先执行某些基本验证组(如 Default
组),然后再执行其他验证组。可以使用 @GroupSequence
来定义验证的执行顺序。
import jakarta.validation.GroupSequence;
@GroupSequence({Default.class, CreateGroup.class, UpdateGroup.class})
public interface OrderedValidation {}
这样,当使用 OrderedValidation
作为验证组时,验证器会先执行 Default
组的验证,然后执行 CreateGroup
组,最后执行 UpdateGroup
组。如果某一组的验证失败,后续的验证将不会执行。
在验证时,你可以这样调用:
Set<ConstraintViolation<User>> violations = validator.validate(user, OrderedValidation.class);
4. 在 Spring 中使用分组验证
如果你在 Spring 项目中使用 Jakarta Bean Validation 或 Hibernate Validator,分组验证也可以通过 @Validated
注解在控制器或服务中使用。
使用示例:
在 Spring 中的控制器或服务层中,你可以通过 @Validated
注解指定要使用的分组。
@RestController
public class UserController {
@PostMapping("/createUser")
public ResponseEntity<String> createUser(@RequestBody @Validated(CreateGroup.class) User user) {
// 创建用户的逻辑
return ResponseEntity.ok("用户创建成功");
}
@PutMapping("/updateUser")
public ResponseEntity<String> updateUser(@RequestBody @Validated(UpdateGroup.class) User user) {
// 更新用户的逻辑
return ResponseEntity.ok("用户更新成功");
}
}
在这个例子中,@Validated(CreateGroup.class)
和 @Validated(UpdateGroup.class)
注解分别在不同的 API 方法中应用,分别在创建和更新用户时执行不同的验证逻辑。
5. Hibernate Validator 的扩展分组功能
Hibernate Validator 是 Jakarta Bean Validation 的实现,它在标准规范基础上添加了一些扩展功能。关于分组验证,Hibernate Validator 提供了以下扩展功能:
a. Group Conversion
在某些情况下,Hibernate Validator 允许将嵌套对象中的一个分组自动转换为另一个分组。这种转换有助于在复杂对象之间进行不同的分组映射。
public class Parent {
@Valid
@ConvertGroup(from = Default.class, to = ChildGroup.class)
private Child child;
}
在这个例子中,当 Parent
对象被验证时,Default
组的验证在 Child
对象上被转换为 ChildGroup
组的验证。
b. 在集合元素上应用分组
你还可以在集合的每个元素上应用分组验证,例如验证列表中的每个元素是否符合特定的分组规则:
public class GroupExample {
@NotEmpty
@Valid
private List<@Validated(CreateGroup.class) User> users;
// getters 和 setters
}