Spring MVC и JSR 303 - ручная проверка - PullRequest
2 голосов
/ 16 ноября 2010

Я использую Spring MVC 3 и JSR 303. У меня есть объект поддержки формы, в котором есть бины разных типов.В зависимости от значения параметра запроса мне придется выбрать компонент для проверки и сохранения.Я не могу использовать @Valid для проверки, так как bean-компонент для проверки неизвестен до времени выполнения.

Мне удалось внедрить javax.validation.Validator в контроллер, но я не уверен, как проверитьbean с ним и хранить любые ошибки в BindingResult/Error «Spring way».

Мне нужно сделать это в методе обработчика, а не в методе initBinder, из-за сопоставления запроса.1009 *

[edit]

Проблема, с которой я столкнулся с validate(Object, Errors), заключается в том, что он не распознает вложенные бины.Доступ к проверяемому компоненту осуществляется через foo.getBar (). GetBean (), где foo - это объект поддержки формы.Когда я делаю validate(foo.getBar().getBean(), errors), я получаю следующее сообщение об ошибке:

JSR-303 validated property 'property-name' does not have a corresponding accessor for Spring data binding

Кто-нибудь делал что-то подобное раньше?Благодаря.

Ответы [ 3 ]

5 голосов
/ 16 ноября 2010

Да, магический класс, который вы ищете, это org.springframework.validation.beanvalidation.SpringValidatorAdapter

Этот класс получает javax.validation.Validator, внедренный в него и содержит код, как следует из его названия, для "адаптации" вывода обратно в знакомый Errors объект. Это то, что используется внутри для обработки, когда вы помещаете @Valid в параметр метода.

Вы можете получить их напрямую, добавив явный LocalValidatorFactoryBean в ваш сервлет диспетчера. Просто внедрите экземпляр этого в качестве экземпляра стандартного интерфейса Spring Validator и используйте его так, как если бы вы использовали любой провайдер проверки пружины 'pre jsr-303'.

4 голосов
/ 16 ноября 2010

Просто предположение, но вы пробовали

 errors.pushNestedPath("bar.bean"); // Path to the nested bean
 validate(foo.getBar().getBean(), errors)
 errors.popNestedPath();

Вот как BindingResult обычно используется для проверки правильности вложенных бинов.

0 голосов
/ 16 ноября 2010

Способ, который я видел, состоит в том, чтобы использовать стандартный валидатор JSR-303 (что бы вы ни вводили), чтобы получить нарушения (т. Е. Set<ConstraintViolaion<T>>)

Затем используйте код, аналогичныйк этому внутри LocalValidatorFactoryBean для преобразования между этими нарушениями и ошибками Spring:

public static <T> void convert(Errors errors, Collection<ConstraintViolation<T>> violations) {
        for (ConstraintViolation<?> violation : violations) {
            String field = violation.getPropertyPath().toString();
            FieldError fieldError = errors.getFieldError(field);
            if (fieldError == null || !fieldError.isBindingFailure()) {
                errors.rejectValue(field, violation.getConstraintDescriptor().getAnnotation().annotationType()
                        .getSimpleName(), getArgumentsForConstraint(errors.getObjectName(), field, violation
                        .getConstraintDescriptor()), violation.getMessage());
            }
        }
    }

    private static Object[] getArgumentsForConstraint(String objectName, String field,
            ConstraintDescriptor<?> descriptor) {
        List<Object> arguments = new LinkedList<Object>();
        String[] codes = new String[] { objectName + Errors.NESTED_PATH_SEPARATOR + field, field };
        arguments.add(new DefaultMessageSourceResolvable(codes, field));
        arguments.addAll(descriptor.getAttributes().values());
        return arguments.toArray(new Object[arguments.size()]);
    }
...