Hibernate Validator不验证JSON数组中的元素

时间:2018-02-08 15:40:53

标签: java json validation

我想使用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数组进行递归验证?

1 个答案:

答案 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)