2016-08-17 3 views
2

Я пытаюсь реализовать некоторую пользовательскую логику проверки для конечной точки загрузки весны, используя комбинацию JSR-303 Bean Validation API и Spring's Validator.Реализация пользовательской логики проверки для конечной точки загрузки весны с использованием комбинации JSR-303 и Validator

На основе диаграммы класса Validator представляется возможным расширить один из CustomValidatorBean, SpringValidatorAdapter или LocalValidatorFactoryBean добавить некоторые пользовательскую логику проверки в перекрытый метод validate(Object target, Errors errors).

Validator class diagram.

Однако, если я создаю валидатор, распространяющий любой из этих трех классов, и зарегистрирую его с помощью @InitBinder, его метод validate(Object target, Errors errors) никогда не вызывается и проверка не выполняется. Если я удалю @InitBinder, то весна-валидатор по умолчанию выполняет команду JSR-303 Bean Validation.

Rest Контроллер:

@RestController 
public class PersonEndpoint { 

    @InitBinder("person") 
    protected void initBinder(WebDataBinder binder) { 
     binder.setValidator(new PersonValidator()); 
    } 

    @RequestMapping(path = "/person", method = RequestMethod.PUT) 
    public ResponseEntity<Person> add(@Valid @RequestBody Person person) { 

     person = personService.save(person); 
     return ResponseEntity.ok().body(person); 
    } 
} 

валидатора:

public class PersonValidator extends CustomValidatorBean { 

    @Override 
    public boolean supports(Class<?> clazz) { 
     return Person.class.isAssignableFrom(clazz); 
    } 

    @Override 
    public void validate(Object target, Errors errors) { 
     super.validate(target, errors); 
     System.out.println("PersonValidator.validate() target="+ target +" errors="+ errors); 
    } 

} 

Если мой валидатор реализует org.springframework.validation.Validator то его метод validate(Object target, Errors errors) называется, но JSR-303 Bean Validation не выполняется до него. Я могу реализовать свой собственный JSR-303 проверки подобно тому, как SpringValidatorAdapter реализует JSR-303 Bean Validation, но там должен быть способ продлить его вместо:

@Override 
    public void validate(Object target, Errors errors) { 
     if (this.targetValidator != null) { 
      processConstraintViolations(this.targetValidator.validate(target), errors); 
     } 
    } 

Я посмотрел на использование пользовательских JSR-303 ограничений, чтобы избежать использования org.springframework.validation.Validator все вместе, но должен быть способ сделать работу пользовательского валидатора.

validation documentation Пружина не супер ясно, на объединении двух:

Приложение может также зарегистрировать дополнительные экземпляры Спринг Validator за DataBinder, например, как описано в разделе 9.8.3, «Настройка DataBinder». Это может быть полезно для подключения логики проверки без использования аннотаций.

А потом на нем затрагивает настройки нескольких экземпляров валидатор

DataBinder также может быть сконфигурирован с несколькими экземплярами средства проверки через dataBinder.addValidators и dataBinder.replaceValidators. Это полезно при объединении глобально настроенной проверки Bean с помощью Spring Validator, настроенной локально на экземпляре DataBinder. Видеть ???.

Я использую весенний ботинок 1.4.0.

+0

Я не совсем уверен, что это ясно, каков ваш реальный вопрос. Более того, я думаю, это поможет, если вы поделитесь полным примером (например,весь код). Тогда нам легче помочь. –

+0

Вы прочитали документацию? Внесите только свою собственную логику в 'Validator' и используйте' addValidators' вместо 'setValidator'. Это вызовет как JSR-303 (по умолчанию настроенный валидатор), так и ваш пользовательский. Однако, вероятно, вам лучше использовать проверку достоверности/ограничение JSR-303 вместо использования двух разных механизмов. –

+0

Спасибо @ M.Deinum - используя 'addValidators' вместо' setValidator' сделал трюк. Я также согласен с тем, что использование JSR-303, метод @AssertTrue, основанный исключительно на проверке кросс-полей, вероятно, является более чистым решением. Пример кода можно найти на странице https://github.com/pavelfomin/spring-boot-rest-example/tree/feature/custom-validator. В примере проверка среднего имени выполняется с помощью настраиваемой весны валидатор, а проверка имени проверяется по умолчанию для проверки достоверности данных jsr 303 . – pavel

ответ

3

Per @ M.Deinum - с помощью addValidators() вместо setValidator() сделал трюк. Я также согласен с тем, что использование JSR-303, аннотация для метода на основе метода @AssertTrue, специально для проверки поперечных полей, вероятно, является более чистым решением. Пример кода доступен по адресу https://github.com/pavelfomin/spring-boot-rest-example/tree/feature/custom-validator. В этом примере проверка среднего имени выполняется с помощью настраиваемого весового валидатора, а проверка имени используется обработчиком jsr 303 по умолчанию.

+0

'@AssertTrue, основанная на методе аннотация, специально для проверки кросс-полей, вероятно, является более чистым решением' IMHO, более чистым решением является написать собственный JSR-303 валидатор (пример: http://stackoverflow.com/questions/1972933/cross-field -validation-с-гибернации-валидатор-JSR-303). –