“合并”两个端点时用于Javax验证注释重用的模式

时间:2019-05-07 11:32:10

标签: java validation javax.validation

我有一个API,其中包含两个实体FooBar,它们之间具有一对多的关系,即每个Bar必须引用一个Foo

我有同时创建FooBar的端点-这些端点具有使用javax验证定义的各自的DTO。

public class CreateFooDto {
  @NotNull public Integer field1;
  @Length(min=1, max=8) public String field2;
}

public class CreateBarDto {
  @NotNull public Boolean field1;
  @NotEmpty public String field2;

  @NotNull public String fooId; // the foreign key to Foo
}

现在,我想要一个新的终结点,它可以将Bar Foo一起创建并链接起来,而不是先创建Foo然后创建Bar传递了fooId。除了需要CreateBarDto.fooId之外,我将需要所有具有相同验证的相同字段。理想情况下,我想重用已经定义的javax验证,而不是重复它们。

我想将现有DTO嵌套在新端点的组合DTO中,但是@NotNull上的CreateBarDto.fooId存在问题-实际上不是 。到目前为止,我想出的最佳解决方案是:

public class CreateBarWithFooDto {
  @Valid public CreateFooDto foo;
  @Valid public CreateBarDto bar;
}

public class CreateBarDto {
  @NotNull public Boolean field1;
  @NotEmpty public String field2;

  public String fooId; // the foreign key to Foo
  public boolean fooIdNotRequired; // optional flag to indicate fooId not required

  @AssertTrue
  public boolean isFooIdRequired() {
    return fooIdNotRequired || fooId != null;
  }
}

虽然可行,但确实很笨拙。只是想知道是否有人可以建议像这样的Javax验证重用的更好模式,或者是否有我不知道的Javax注释可能对此有所帮助?

1 个答案:

答案 0 :(得分:1)

一种选择是使用验证组。 javax.validation.groups 的Javadoc说:

  

组定义约束的子集。无需验证给定对象图的所有约束,而是仅根据目标组验证子集。

     

每个约束声明定义它所属的组的列表。如果未明确声明任何组,则约束属于默认组。

     

应用验证时,将传递目标组列表。如果没有明确传递任何组,则使用javax.validation.groups.Default组。

因此,在您的 CreateBarDto 中举个例子,我们可以有一个新的组 MyFirstGrup.class ,该组仅用于对field1和field2的验证

public class CreateBarDto {
  @NotNull(groups = {MyFirstGrup.class}) 
  public Boolean field1;
  @NotEmpty(groups = {MyFirstGrup.class})
  public String field2;

  @NotNull public String fooId; // the foreign key to Foo
}

您现在需要触发特定的组,通常是通过

validator.validate(yourBean, MyFirstGrup.class);

如果使用Spring,请检查@Validated批注,该批注支持指定您需要运行的组。更多信息here