JSR303 - 应用按顺序定义的所有验证组

时间:2014-11-27 15:20:10

标签: java spring bean-validation hibernate-validator

我有一个我想要进行条件验证的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组。

1 个答案:

答案 0 :(得分:1)

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

  

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

请参阅http://beanvalidation.org/1.1/spec/#constraintdeclarationvalidationprocess-groupsequence-groupsequence

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