Я пытаюсь настроить проверку форм JSR-303 с использованием Spring MVC. У меня все настроено правильно (или, по крайней мере, я думаю, что и есть), и проверки работают в основном правильно. Однако, если у меня есть объект команды, который содержит коллекцию объектов, которые я хочу проверить, и я комментирую эту коллекцию с помощью @Valid, поставщик Hibernate JSR-303 не предоставляет правильный propertyPath. Свойство Property внутри объекта ContraintViolation должно быть заполнено как list[0].bar
и list[1].bar
, но валидатор Hibernate просто предоставляет list[].bar
и list[].bar
. Это вызывает исключение NumberFormatException, когда метод Spring SpringValidatorAdaptor.validate() пытается добавить ошибки на уровне поля (поскольку он внутренне ожидает, что число будет существовать в этих скобках).Проверка Hibernate JSR303 и некорректно сгенерированное свойствоPath
Использование spring-context-3.0.5 и hibernate-validator-4.1.0.Final (я также пробовал 4.0.2.GA и 4.2.0.Beta2 и получил те же результаты), я написал небольшой блок-тест чтобы проиллюстрировать проблему:
package com.foo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.constraints.NotEmpty;
import org.junit.Test;
import org.springframework.util.AutoPopulatingList;
public class ValidatorTest {
class Person {
@NotEmpty
private String name;
@NotEmpty
@Valid
private Collection<Foo> list = new AutoPopulatingList<Foo>(Foo.class);
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Collection<Foo> getList() {
return list;
}
public void setList(Collection<Foo> foos) {
this.list = foos;
}
}
class Foo {
@NotEmpty
private String bar;
public void setBar(String bar) {
this.bar = bar;
}
public String getBar() {
return bar;
}
}
@Test
public void testValidator() throws Exception {
Foo foo0 = new Foo();
foo0.setBar("");
Foo foo1 = new Foo();
foo1.setBar("");
Collection<Foo> list = new ArrayList<ValidatorTest.Foo>();
list.add(foo0);
list.add(foo1);
Person person = new Person();
person.setName("Test Person");
person.setList(list);
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(person);
for (ConstraintViolation<Person> constraintViolation : violations) {
System.out.println(constraintViolation);
}
}
}
выше тест производит следующий вывод:
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=list[].bar, rootBeanClass=class com.foo.ValidatorTest$Person, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=list[].bar, rootBeanClass=class com.foo.ValidatorTest$Person, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ошибки, которые она производит являются правильными; однако свойствоPath не является (по крайней мере, из того, что я понимаю).
Теперь, если я заменил реализацию JSR-303 Hibernate на Apache (org.apache.bval.bundle-0.2-incubating - используя отмеченные зависимости here), я получаю вывод, который я ожидаю. Это тот же самый тест, но с использованием аннотаций JSR-303 от Apache вместо Hibernate. Обратите внимание на индексы, которые сейчас существуют в области PropertyPath:
ConstraintViolationImpl{[email protected], propertyPath='list[0].bar', message='may not be empty', [email protected], value=}
ConstraintViolationImpl{[email protected], propertyPath='list[1].bar', message='may not be empty', [email protected], value=}
По разным причинам, я, вероятно, застрял с помощью реализации библиотеки Hibernate JSR-303. Есть ли что-то, что я делаю, это заставляет валидатор Hibernate не заполнять эти индексы? Я стараюсь избегать ручного управления ошибками в контроллерах Spring, насколько это возможно.
Спасибо за любую помощь, которую вы можете предоставить!