【问题标题】:Hibernate Validator doesn't validate elements in a JSON arrayHibernate Validator 不验证 JSON 数组中的元素
【发布时间】:2018-02-08 15:40:53
【问题描述】:

我想使用 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}'}]

如您所见,Personarray 内的 PersonArray 递归验证了所需的 name 属性,但 Person[] 不验证。有没有办法对顶级 JSON 数组进行递归验证?

【问题讨论】:

    标签: java json validation


    【解决方案1】:

    挖掘 hibernate-validator 和 validation-api jars 我发现你需要在你的类中使用验证注释来触发验证过程,而 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)
    

    【讨论】:

    • 感谢领导!你知道我是否可以在Person[] 上配置验证器,让它和@Valid 做同样的事情吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多