约束不起作用的 OVal 激活规则
OVal activation rules for constraints not working
我正在尝试按照他们的 documentation 实施 OVal 的激活规则,但似乎 运行 遇到了问题 找到变量 我' m 用于比较。不幸的是,除了他们文档中的一小部分之外,网上没有太多关于该主题的内容。
我要解决的问题的另一部分是使用 @Guarded
注释使它也适用于 构造函数验证 。这在没有我对 的回答中描述的约束规则的情况下工作正常,但当我在 JavaScript 或 [ 中添加激活规则时却不行=52=].
3.4. Declaring activation rules for constraints
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.fieldA
、window.fieldA
、fieldA
和 __fieldA
更新
JavaScript 似乎适用于私有字段,只要它具有 public getter.
我已经通过执行以下操作并切换到 groovy 而不是 developer 所建议的 JavaScript 来解决问题。
The JavaScript Engine Rhino cannot directly access private fields. E.g. something like "javascript:_this.myPrivateField != null && _this.myPrivateField.length > 10" will always return false, no matter the value of the private field. Rhino apparently does not raise an exception if it cannot access the private field.
I would recommend you to use groovy instead of javascript for constraint activation.
For most scripting runtimes (including JavaScript) the statement _this.someVariable will result in the invocation of the _this.getSomeVariable() getter and not in a direct access of a private field with the same name.
在我的代码示例的第一行中,如果您要验证的对象有任何 public getter 方法,则 (checkInvariants = false)
是必需的,否则它将导致 WhosebugError
不幸的是,按照我在问题中发布的方式在构造函数中添加验证不起作用。因此,为了解决这个问题,我需要将验证添加到字段中,并将 @PostValidateThis
注释添加到构造函数中。
示例 Pojo 在调用构造函数后使用验证。
@Guarded(checkInvariants = false)// removing this results in WhosebugError
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);
}
}
我正在尝试按照他们的 documentation 实施 OVal 的激活规则,但似乎 运行 遇到了问题 找到变量 我' m 用于比较。不幸的是,除了他们文档中的一小部分之外,网上没有太多关于该主题的内容。
我要解决的问题的另一部分是使用 @Guarded
注释使它也适用于 构造函数验证 。这在没有我对
3.4. Declaring activation rules for constraints
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.fieldA
、window.fieldA
、fieldA
和 __fieldA
更新 JavaScript 似乎适用于私有字段,只要它具有 public getter.
我已经通过执行以下操作并切换到 groovy 而不是 developer 所建议的 JavaScript 来解决问题。
The JavaScript Engine Rhino cannot directly access private fields. E.g. something like "javascript:_this.myPrivateField != null && _this.myPrivateField.length > 10" will always return false, no matter the value of the private field. Rhino apparently does not raise an exception if it cannot access the private field.
I would recommend you to use groovy instead of javascript for constraint activation. For most scripting runtimes (including JavaScript) the statement _this.someVariable will result in the invocation of the _this.getSomeVariable() getter and not in a direct access of a private field with the same name.
在我的代码示例的第一行中,如果您要验证的对象有任何 public getter 方法,则 (checkInvariants = false)
是必需的,否则它将导致 WhosebugError
不幸的是,按照我在问题中发布的方式在构造函数中添加验证不起作用。因此,为了解决这个问题,我需要将验证添加到字段中,并将 @PostValidateThis
注释添加到构造函数中。
示例 Pojo 在调用构造函数后使用验证。
@Guarded(checkInvariants = false)// removing this results in WhosebugError
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);
}
}