Jakarta Bean Validation:如何为CreditTransfer的sender设置条件地址约束
嵌套对象的差异化字段验证方案
现有类结构
public class CreditTransfer { private String messageId; private Party sender; private Party receiver; private BigDecimal amount; //getters and setters } public class Party { private String name; private PostalAddress address; private Account account; //getters and setters }
问题描述
是否可以在不给Party类添加全局字段约束的前提下,仅对CreditTransfer类中的sender嵌套对象验证其address属性必须为null,而receiver的address属性则必须非null?直接在Party类的address字段标注@Null会导致所有Party实例的address都必须为null,无法满足receiver的要求。
可行方案
方案一:分组验证(推荐)
通过分组验证可以实现差异化规则,且无需修改Party类的全局约束:
- 在
Party类中为address字段添加分组约束,并定义对应的分组接口:
import jakarta.validation.constraints.Null; import jakarta.validation.constraints.NotNull; public class Party { private String name; // 仅在SenderValidationGroup分组下要求address为null @Null(groups = SenderValidationGroup.class) // 仅在ReceiverValidationGroup分组下要求address非null @NotNull(groups = ReceiverValidationGroup.class) private PostalAddress address; private Account account; //getters and setters // 定义两个验证分组接口 public interface SenderValidationGroup {} public interface ReceiverValidationGroup {} }
- 在
CreditTransfer类中,对sender和receiver字段开启嵌套验证,并指定对应的验证分组:
import jakarta.validation.Valid; import jakarta.validation.groups.ConvertGroup; import jakarta.validation.groups.Default; public class CreditTransfer { private String messageId; @Valid // 将默认分组转换为SenderValidationGroup,验证sender的address必须为null @ConvertGroup(from = Default.class, to = Party.SenderValidationGroup.class) private Party sender; @Valid // 将默认分组转换为ReceiverValidationGroup,验证receiver的address必须非null @ConvertGroup(from = Default.class, to = Party.ReceiverValidationGroup.class) private Party receiver; private BigDecimal amount; //getters and setters }
这种方式不会给Party类添加全局约束,仅在CreditTransfer的不同字段验证时应用对应规则,完全满足需求。
方案二:类内方法级验证
如果不想修改Party类,也可以直接在CreditTransfer内通过方法验证实现规则:
import jakarta.validation.Valid; import jakarta.validation.constraints.AssertTrue; public class CreditTransfer { private String messageId; @Valid private Party sender; @Valid private Party receiver; private BigDecimal amount; // 验证sender的address必须为null @AssertTrue(message = "sender的address必须为null") public boolean isSenderAddressNull() { return sender == null || sender.getAddress() == null; } // 验证receiver的address必须非null @AssertTrue(message = "receiver的address不能为空") public boolean isReceiverAddressNotNull() { return receiver != null && receiver.getAddress() != null; } //getters and setters }
这种方式无需改动Party类,直接在CreditTransfer内部完成差异化验证。
内容的提问来源于stack exchange,提问作者Federico
相关产品推荐
相关产品推荐

