Подтвердить что ты не робот

Почему мой валидатор Spring 3 проверяет все на модели?

У меня есть контроллер spring 3 с валидатором для одного из методов. Он настаивает на проверке каждого объекта на модели. Кто-нибудь сможет объяснить мне, почему он это делает, или если я что-то делаю неправильно?

В соответствии с документами, 5.7.4.3 Настройка JSR-303 Validator для использования с помощью spring MVC (http://static.springsource.org/spring/docs/3.0.0.RC3/spring-framework-reference/html/ch05s07.html)

С JSR-303 один экземпляр javax.validation.Validator обычно проверяет все объекты модели, объявляющие ограничения проверки. Чтобы настроить поддерживающий JSR-303 валидатор с помощью spring MVC, просто добавьте поставщика JSR-303, такого как Hibernate Validator, в свой путь к классам. spring MVC обнаружит его и автоматически включит поддержку JSR-303 для всех контроллеров.

Пример:

@Controller
public class WhaleController {

        @Autowired
        private Validator myValidator;

        @Autowired
        private WhaleService whaleService;

        @InitBinder
        protected void initBinder(WebDataBinder binder) {
                binder.setValidator(this.myValidator);
        }

        @RequestMapping(value="/save-the-whales")
        @Transactional
        public void saveTheWhales(@Valid WhaleFormData formData, BindingResult errors, Model model) {
                if (!errors.hasFieldErrors()) {
                        Whale whale = new Whale();

                        whale.setBreed( formData.getBreed() );

                        this.whaleService.saveWhale( whale );

                        model.addAttribute("whale", whale);

                }
                model.addAttribute("errors", errors.getFieldErrors());
        }

}

При запуске он будет жаловаться на то, что Whale является недопустимой мишенью для myValidator (который установлен для проверки WhaleFormData и делает это отлично). Кит - это POJO без ограничений проверки, аннотации и без каких-либо настроек. Через пробную версию и ошибку я обнаружил, что любой объект, помещенный в модель, будет пытаться быть проверенным и сбой, если валидатор не настроен для его обработки. Примитивы просто прекрасны.

Может ли кто-нибудь сказать мне, почему это так, укажите мне соответствующую документацию и/или скажите мне, как лучше всего поместить что-то на модель, не подтвердив ее?

В вышеприведенном случае я хотел бы поместить "кит" в модель, так как теперь у нее будет уникальный whaleId(), который он получил из моего уровня персистентности.

Спасибо!

4b9b3361

Ответ 1

Я предполагаю, что это поведение недостаточно хорошо описано в документации.

Проблема вызвана следующим:

  • По умолчанию метод @InitBinder -annotated вызывается для каждого не примитивного атрибута модели, как входящего, так и исходящего (целью его вызова для исходящих аттитов является возможность зарегистрировать пользовательские PropertyEditor s, которые используются тегами формы при рендеринге формы).

  • DataBinder.setValidator() содержит защитную проверку, вызывающую Validator.supports() и выдает исключение, если возвращается false. Таким образом, нет попытки выполнить проверку, только раннюю проверку.

Решение состоит в том, чтобы ограничить область действия @InitBinder конкретным атрибутом:

@InitBinder("whaleFormData")
protected void initBinder(WebDataBinder binder) { ... }