【问题标题】:Bean Validation - constructor/factory parameterBean Validation - 构造函数/工厂参数
【发布时间】:2015-06-04 12:48:44
【问题描述】:

我有一个 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。因此客户端可以发送 first 和 last JSON 格式的字段,也可以只发送 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 封装)。

我可以简单地忽略异常,并将字段留空,这将返回 422,因为 @NotNull 约束,但错误消息不会像应有的那样清晰。

我尝试在@JsonProperty 参数旁边添加我的@Cidr 验证器,但这似乎没有效果。我的理解是验证发生在 Jackson 完成创建 Dtos 之后,因此使用我的@JsonCreator 方法可能无法解决此问题。所以我也愿意接受重构建议。

【问题讨论】:

    标签: java jackson bean-validation jersey-2.0 hibernate-validator


    【解决方案1】:

    我不是将 Bean Validation 精确集成到 jackson 中的专家,但我认为它只是在进行实际的属性验证。这意味着正如您已经指出的那样,首先创建实体,然后验证属性。

    Bean Validation(从 1.1 版开始)还提供所谓的方法验证,在这种情况下,您可以将 Cidr 约束放在方法的字符串参数上,但如前所述,我认为没有为此集成在杰克逊中。

    还有一件事 ;-) - 在 Bean Validation 中,静态方法和属性通常被排除在验证之外(另请参阅 http://beanvalidation.org/1.1/spec/#d0e2815)。

    关于解决方法,我想到了一件事(尽管感觉有点复杂)。编写自定义类级别IpRange 约束。在类约束中,您将获得一个 IpRangeDto 实例,并由您来验证整个对象并为任何违规选择正确的错误消息。如果您将 cidr 属性添加到在调用fromCidr 时设置的 dto,那么您将获得验证和选择正确错误消息所需的所有信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-07
      • 2012-01-31
      • 2021-12-15
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多