1

我有一个包含两个实体FooBar一对多关系的 API,即每个实体都Bar必须引用一个Foo.

我有端点来创建两者Foo,并且Bar- 这些端点具有使用 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 and 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 注释可能有助于解决这个问题?

4

1 回答 1

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 注释。更多信息在这里

于 2019-05-07T12:52:29.263 回答