2010-11-15 5 views
2

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

Я смог ввести контроллер javax.validation.Validator, но я не уверен, как его проверять и хранить ошибки в BindingResult/Error по принципу «Весна».

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

[править]

Проблема у меня с 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 

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

ответ

4

только предположение, но вы пробовали

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

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

5

Да, волшебный класс, который вы ищете, org.springframework.validation.beanvalidation.SpringValidatorAdapter

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

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

+0

Спасибо, но все же не повезло. Не могли бы вы увидеть редактирование? –

0

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

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

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()]); 
    } 
Смежные вопросы