Есть ли способ использовать более одного валидатора с аннотированным контроллером Spring 3? - PullRequest
3 голосов
/ 20 марта 2012

У меня есть контроллер Spring 2.x, который расширяет SimpleFormController, который устарел с весны 3 в пользу аннотированных контроллеров. Поэтому я пытаюсь преобразовать его для использования @Controller, с @InitBinder и @Valid для проверки формы. Однако я не могу найти способ использовать несколько валидаторов с контроллером Spring 3.x. Как мне это сделать?

Вот как выглядит bean def моего контроллера:

<bean name="/s/account" class="mywork.AccountSettingsController"
    p:formView="forms/account"
    p:successView="redirect:/app/s/account"
    p:commandName="accountSettingsForm">
    <property name="validators">
        <list>
            <ref bean="emailFormatValidator" />
            <ref bean="uniqueEmailValidator" />
            <ref bean="changeEmailValidator" />
            <ref bean="passwordWithConfirmationValidator" />
            <ref bean="changePasswordValidator" />
        </list>
    </property>
</bean>

Это контроллер страницы, который позволяет пользователю изменять свой адрес электронной почты и пароль. Бины-валидаторы являются устаревшим кодом, но я предполагаю, что они были разделены на отдельные классы для лучшей возможности повторного использования.

Я пытаюсь переместить все это в сам класс контроллера, используя аннотации:

@Controller
@Secured({BaseController.ROLE_LOGGED_IN})
@RequestMapping("/s/account")
public class AccountSettingsController extends BaseController {
    private static final String FORM_URL = "/forms/account";
    private static final String FORM_NAME = "accountSettingsForm";

    @InitBinder(FORM_NAME)
    public void initBinder(WebDataBinder binder) {
        // TODO: how to inject > 1 validator for the form?
        binder.setValidator(...);
    }

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView get() {
        ChangePasswordOrEmailForm form = new ChangePasswordOrEmailForm();
        ...
        return new ModelAndView(FORM_URL, FORM_NAME, form);
    }
    ...
}

Насколько я могу судить, Spring 3 предполагает отношение 1: 1 между: Controller-Form-WebDataBinder-Validator. Я мог бы создать составной валидатор, который объединит 5 отдельных компонентов валидатора и делегирует им вызовы Validator#supports() и Validator#validate(), но действительно ли это лучшее решение?

Ответы [ 3 ]

3 голосов
/ 21 марта 2012

Другой, который, как я думал, имел ValidatorFacade, который, в свою очередь, вызывает все остальные валидаторы один за другим, таким образом, вам не нужно внедрять, а вместо этого присоединяйте ValidatorFacade с initBinder и @Valid перед вашим компонентом формы, автоматически вызовет ValidatorFacade и все позаботились автоматически. Просто мысль.

1 голос
/ 25 февраля 2015

Это была старая проблема.

Добавление комментария сюда:

После весны 3.2.1.RELEASE, DataBinder # addValidators (валидатор ... валидаторы) доступно.

0 голосов
/ 21 марта 2012

Лучшее решение, которое я могу придумать, - добавить коллекцию валидаторов и вручную прокрутить их. Итак, пока я удалил initBinder() из своего класса контроллера, и вот что я добавил:

private List<Validator> accountSettingsValidators;

// Maps & Collections can't be @Autowired (by type OR name), so use the JSR 250 @Resource annotation to autowire by name
@Resource
public void setAccountSettingsValidators(List<Validator> accountSettingsValidators) {
    this.accountSettingsValidators = accountSettingsValidators;
}

@RequestMapping(method = RequestMethod.POST)
protected ModelAndView processSubmit(HttpServletRequest request,
                                     @ModelAttribute(FORM_NAME) ChangePasswordOrEmailForm form,
                                     BindingResult bindingResult) {
    for (Validator validator : this.accountSettingsValidators) {
        ValidationUtils.invokeValidator(validator, form, bindingResult);
    }

    if (bindingResult.hasErrors()) {
        return new ModelAndView(FORM_URL, FORM_NAME, form);
    }

    // process validated form
}

В моем formControllers.xml Spring config я создаю список валидаторов для внедрения:

<util:list id="accountSettingsValidators">
    <ref bean="emailFormatValidator" />
    <ref bean="uniqueEmailValidator" />
    <ref bean="changeEmailValidator" />
    <ref bean="passwordWithConfirmationValidator" />
    <ref bean="changePasswordValidator" />
</util:list>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...