我有一个dto对象,它使用第一个和最后一个字段保存IP范围。使用dropwizard(jersey-jackson-hibernate验证器)使用此类进行简单的CRUD操作
public class IpRangeDto {
@JsonCreator
public static IpRangeDto fromCidr(@JsonProperty("cidr") String cidr) {
//Resolve CIDR and assign first and last fields
}
@NotNull
@IpAddress // My custom validator
private String first;
@NotNull
@IpAddress
private String last;
}
为了方便用户,我决定添加另一种创建此对象的方法,即使用CIDR。因此,客户端可以发送JSON中的first
和last
字段,也可以只发送cidr
字段。所以这样做的方法如上所述,使用@JsonCreator。它运作得很好。
"ipRange":{
"first": "15.0.0.1",
"last": "15.0.0.255",
}
"ipRange":{
"cidr": "15.0.0.0/24"
}
我想验证此CIDR值是否为正确格式,以便我可以返回422并显示正确的错误消息。如果我在构造函数/工厂方法中抛出异常,则jersey-jackson直接返回400(即使我抛出ConstraintViolationException
,它由JsonProcessingException
封装。)
我可以简单地忽略异常,并将字段留空,因为@NotNull
约束而返回422但是错误消息不会像它应该的那样清晰。
我尝试在@Cidr
参数旁边添加@JsonProperty
验证程序,但这似乎并不有效。我的理解是在杰克逊完成创建Dtos之后进行验证,因此使用@JsonCreator
方法可能无法解决此问题。所以我也愿意重构建议。
答案 0 :(得分:1)
我不是关于将Bean Validation与jackson完全集成的专家,但我认为它只是在进行实际的属性验证。这意味着正如您已经指出的那样,首先创建实体,然后验证属性。
Bean Validation(从版本1.1开始)也提供了所谓的方法验证,在这种情况下,您可以将Cidr
约束放在方法的字符串参数上,但如上所述,我不认为那里杰克逊为此而整合。
还有一件事;-) - 静态方法和属性通常从Bean验证中的验证中排除(另请参阅http://beanvalidation.org/1.1/spec/#d0e2815)。
关于解决方法,有一件事情会浮现在脑海中(即使感觉有点复杂)。编写自定义类级IpRange
约束。在类约束中,您将传递一个IpRangeDto
实例,由您来验证整个对象并为任何违规选择正确的错误消息。如果你要在调用fromCidr
时设置的dto中添加一个cidr属性,那么你将获得验证和选择正确错误消息所需的所有信息。