【问题标题】:JSR303 - Apply all validation-groups defined in sequenceJSR303 - 应用按顺序定义的所有验证组
【发布时间】:2015-01-26 05:53:24
【问题描述】:

我有一个要进行条件验证的 bean。为此,我定义了一个DefaultGroupSequenceProvider<MyObject>,它返回要验证的组列表。

现在,当验证违反序列中多个组中的约束的对象时,只有第一个失败的组返回它的结果。我想在所有违规行为上得到一个错误,而不仅仅是第一组失败的那些。

我认为这不需要代码示例,但如果我错了,我很乐意提供。

我在创建序列时遵循了这个http://kh-yiu.blogspot.com/2014/04/conditional-bean-validation-using.html。如果这很重要,我们会使用 Spring。

请注意,这是可行的,因为不可能将无效 bean 报告为有效。但是,如果用户有一些输入打破了 3 个约束,并且我返回了 2 个失败,那么一旦第一个字段得到纠正,用户就会在最后一个字段上得到另一个失败。不完全是用户友好的。

例子:

豆子

@GroupSequenceProvider(BeanSequenceProvider.class)
public class MyBean {
    @NotEmpty
    private String name;

    @NotNull
    private MyType type;

    @NotEmpty(groups = Special.class)
    private String lastName;

    // Getters and setters        
}

枚举类型

public enum MyType {
    FIRST, SECOND
}

提供者

public class BeanSequenceProvider implements DefaultGroupSequenceProvider<MyBean> {
    @Override
    public List<Class<?>> getValidationGroups(final MyBean object) {
        final List<Class<?>> classes = new ArrayList<>();

        classes.add(MyBean.class);

        if (object != null && object.getType() == MyType.SECOND) {
            classes.add(Special.class);
        }

        return classes;
    }

组注释

public interface Special {
}

测试类

public class MyBeanTest {

    private static Validator validator;

    private MyBean objectUnderTest;

    @BeforeClass
    public static void setUpOnce() throws Exception {
        final ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();

        validator = validatorFactory.getValidator();
    }

    @Before
    public void setUp() throws Exception {
        objectUnderTest = new MyBean();

        objectUnderTest.setName("Simen");
        objectUnderTest.setType(MyType.FIRST);
        objectUnderTest.setLastName("Woop");
    }

    @Test
    public void testValid() throws Exception {
        assertThat(validator.validate(objectUnderTest), is(empty()));
    }

    @Test
    public void testMissingName() throws Exception {
        objectUnderTest.setName(null);

        assertThat(validator.validate(objectUnderTest), hasSize(1));
    }

    @Test
    public void testMissingLastName() throws Exception {
        objectUnderTest.setLastName(null);

        assertThat(validator.validate(objectUnderTest), is(empty()));

        objectUnderTest.setType(MyType.SECOND);

        assertThat(validator.validate(objectUnderTest), hasSize(1));

        objectUnderTest.setName(null);

        assertThat(validator.validate(objectUnderTest), hasSize(2));
    }

最后一个断言失败,因为有一个违规,而不是 2 个。因为在默认组中违反了约束,所以 Special 组没有被违反。

【问题讨论】:

  • 我从来没有用过这个,但也许你应该使用DefaultGroupSequenceProvider&lt;?&gt;以外的东西?基本上你的意思是你不希望错误按顺序返回,所以使用别的东西?
  • 这就是我的想法,但我的谷歌搜索没有给我任何选择。有什么想法吗?
  • 嗯.. 您选择GroupSequenceProvider 有什么原因吗?
  • 我必须获取我正在验证的实例,因为应该验证哪些组取决于该对象上的枚举值。我通过谷歌搜索找到了我在说明中提供的链接,只要所有违规行为都针对同一组,该链接就可以使用。
  • 好吧,好吧,我不认为我可以回答这个问题。我将它添加到我的收藏夹中,希望有人能接管它。祝你好运!

标签: java spring bean-validation hibernate-validator


【解决方案1】:

好的,现在我明白你的问题了。答案是,如果给定组中存在一个或多个违规行为,验证将停止。引用规范:

第 4.6 节“验证例程”中定义了处理组; 如果序列中处理的组之一生成一个或多个 违反约束,序列中跟随的组不得 被处理。这可确保仅评估一组约束 如果另一组约束有效。

见http://beanvalidation.org/1.1/spec/#constraintdeclarationvalidationprocess-groupsequence-groupsequence

在您的情况下,Default 组中存在违规行为,这意味着 Special 组永远不会被验证。

【讨论】:

  • 是的,我知道,但我想从所有组中获取所有违规行为,而不是让它短路验证。你知道我有什么办法可以做到吗?我并不特别拘泥于当前的实现,这正是我进行我想要的条件验证的方式。
猜你喜欢
  • 2011-07-08
  • 2017-06-13
  • 2014-09-17
  • 2023-03-15
  • 2013-07-13
  • 2017-09-25
  • 2014-11-05
  • 2020-09-09
  • 2013-01-18
相关资源
最近更新 更多