【问题标题】:OVal activation rules for constraints not working约束的 Oval 激活规则不起作用
【发布时间】:2017-05-16 07:10:44
【问题描述】:

我正在尝试按照他们的documentation 为 OVal 实施激活规则,但似乎遇到了问题查找变量我用于比较。不幸的是,除了他们文档中的一小部分之外,关于该主题的在线内容并不多。

我试图解决的问题的另一部分是使用@Guarded 注释也让这个工作用于构造函数验证。如果没有我对this question 的回答中描述的约束规则,这可以正常工作,但当我在 JavaScriptGroovy 中添加激活规则时则不行。

3.4。声明约束的激活规则

public class BusinessObject
{
    private String fieldA;

    @NotNull(when = "groovy:_this.fieldA != null")
    private String fieldB;
}

我尝试了 JS 和 groovy,并尝试了使用和不使用 _this。删除它会导致:ReferenceError: "someString" is not defined 所以我认为他们在文档中列出的方式是正确的,但我遗漏了一些东西。

字段验证代码:

public class BusinessObject {
    private String fieldA;

    //@NotNull(when = "groovy:_this.fieldA != null") //works for public & private
    @NotNull(when = "javascript:_this.fieldA != null") //only works when fieldA is public
    private String fieldB;

    public BusinessObject(){}

    public BusinessObject(String fieldA, String fieldB) {
        this.fieldA = fieldA;
        this.fieldB = fieldB;
    }
}

构造函数验证代码:

@Guarded
public class BusinessObjectConstructorValidation {
    private String fieldA;
    private String fieldB;

    public BusinessObjectConstructorValidation(
            String fieldA,
            @NotNull(when = "groovy:_this.fieldA != null") String fieldB) {

        this.fieldA = fieldA;
        this.fieldB = fieldB;
    }
}

我如何测试对象:

public class BusinessObjectTest {

    @Test
    public void fieldANullFieldBNotValidatedNoViolations() {
        BusinessObject businessObject = new BusinessObject(null, null);
        Validator validator = new Validator();
        validator.validate(businessObject);
    }

    //This test will fail if the fields are private and using javascript
    //If it's public or using groovy it passes
    @Test
    public void fieldANotNullFieldBValidatedViolationsSizeIsOne() {
        BusinessObject businessObject = new BusinessObject("A", null);
        Validator validator = new Validator();
        List<ConstraintViolation> errors = validator.validate(businessObject);
        System.out.println(errors.size());
        assertThat(errors.size(), is(1));
    }

    @Test
    public void fieldANullFieldBNotNullNoViolations() {
        BusinessObject businessObject = new BusinessObject(null, "B");
        Validator validator = new Validator();
        validator.validate(businessObject);
    }
}

我不确定为什么 JavaScript 版本的行为与 groovy 版本不同,我尝试更改所有我能想到的组合,包括:_this.fieldA__this.fieldAwindow.fieldAfieldA__fieldA

更新 只要有公共 getter,JavaScript 似乎就可以用于私有字段。

【问题讨论】:

    标签: javascript java validation groovy oval


    【解决方案1】:

    按照developer 的建议,我通过执行以下操作并切换到 groovy 而不是 JavaScript 解决了这个问题。

    JavaScript 引擎 Rhino 无法直接访问私有字段。例如。无论私有字段的值如何,诸如“javascript:_this.myPrivateField != null && _this.myPrivateField.length > 10”之类的东西都会返回 false。如果 Rhino 无法访问私有字段,它显然不会引发异常。

    我建议您使用 groovy 而不是 javascript 来激活约束。 对于大多数脚本运行时(包括 JavaScript),语句 _this.someVariable 将导致调用 _this.getSomeVariable() getter,而不是直接访问同名的私有字段。

    在我的代码示例的第一行中,如果您要验证的对象具有任何公共 getter 方法,则需要 (checkInvariants = false),否则将导致 StackOverflowError

    不幸的是,正如我在我的问题中发布的那样,在构造函数中添加验证不起作用。因此,为了解决这个问题,我需要将验证添加到字段并将 @PostValidateThis 注释添加到构造函数。

    调用构造函数后使用验证的示例 Pojo。

    @Guarded(checkInvariants = false)// removing this results in StackOverflowError
    public class User {
        private final String firstName;
        private final String lastName;
        @NotNull(when = "groovy:_this.lastName != null")
        private final Integer age;
    
        @PostValidateThis
        public User(String firstName, String lastName, Integer age) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.age = age;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public Integer getAge() {
            return age;
        }
    }
    

    上述pojo的基本单元测试。

    public class UserTest {
        @Test
        public void userValidParamsNoException() throws Exception {
            User user = new User("foo","bar",123);
            assertThat(user, is(not(nullValue())));
            assertThat(user.getFirstName(), is("foo"));
            assertThat(user.getLastName(), is("bar"));
            assertThat(user.getAge(), is(123));
        }
    
        @Test
        public void userLastNameNullNoException() throws Exception {
            User user = new User("foo",null, null);
            assertThat(user, is(not(nullValue())));
            assertThat(user.getFirstName(), is("foo"));
        }
    
        @Test(expected = ConstraintsViolatedException.class)
        public void userLastNameNotNullAgeNullThrowsException() throws Exception {
            User user = new User("foo","bar", null);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 2017-01-22
      • 1970-01-01
      相关资源
      最近更新 更多