我想使用Hibernate Validator针对JSR 303注释验证JSON数组。虽然验证适用于JSON对象和数组类型的属性(使用@Valid
),但是对于顶级JSON数组的元素,将跳过验证。
例如:
public class ValidationTest {
public static void main(String[] args) throws IOException {
ObjectMapper m = new ObjectMapper();
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
System.out.println(validator.validate(m.readValue("{}", Person.class)));
System.out.println(validator.validate(m.readValue("[{}]", Person[].class)));
System.out.println(validator.validate(m.readValue("{\"array\":[{}]}", PersonArray.class)));
}
}
class Person {
@NotNull
private String name;
public String getName() {
return name;
}
public Person setName(String name) {
this.name = name;
return this;
}
}
class PersonArray {
@Valid
private Person[] array;
public Person[] getArray() {
return array;
}
public PersonArray setArray(Person[] array) {
this.array = array;
return this;
}
}
输出:
[ConstraintViolationImpl{interpolatedMessage='must not be null', propertyPath=name, rootBeanClass=class com.radius.Person, messageTemplate='{javax.validation.constraints.NotNull.message}'}]
[]
[ConstraintViolationImpl{interpolatedMessage='must not be null', propertyPath=array[0].name, rootBeanClass=class com.radius.PersonArray, messageTemplate='{javax.validation.constraints.NotNull.message}'}]
如您所见,所需的name
属性已针对Person
进行了验证,并针对array
内的PersonArray
进行了递归验证,但未针对Person[]
进行验证。有没有办法对顶级JSON数组进行递归验证?
答案 0 :(得分:0)
挖掘hibernate-validator和validation-api jar我发现你需要在类中进行验证注释才能触发验证过程而Person[].class
没有任何这样的数组元素的递归验证不会被启动。似乎BeanDescriptor.isBeanConstrained()
为您的示例返回false。
/**
* Returns {@code true} if the bean involves validation:
* <ul>
* <li>a constraint is hosted on the bean itself</li>
* <li>a constraint is hosted on one of the bean properties</li>
* <li>or a bean property is marked for cascaded validation ({@link Valid})</li>
* </ul>
* <p>
* Constrained methods and constructors are ignored.
*
* @return {@code true} if the bean involves validation, {@code false} otherwise
*/
boolean isBeanConstrained();
一个简单且非侵入性的修复方法如下所示:
import javax.validation.Valid;
public class ValidWrapper<T> {
@Valid
private T[] data;
public ValidWrapper(final T[] _data) {
this.data = _data;
}
public T[] getData() {
return data;
}
}
然后你可以验证任何数组:
validator.validate(m.readValue("{\"data\": [{}]}", ValidWrapper.class)