2012-03-20 1 views
3

SimpleFormController으로 확장되는 Spring 2.x 컨트롤러가 있는데, 주석이 달린 컨트롤러를 선호하여 Spring 3에서 사용되지 않습니다. 그래서 양식 유효성 검사를 위해 @InitBinder@Valid과 함께 @Controller을 사용하도록 변환하려고합니다. 그러나 스프링 3.x 컨트롤러로 여러 개의 유효성 검사기를 사용하는 방법을 찾을 수 없습니다. 어떻게해야합니까? 그것은 사용자가 자신의 이메일 주소와 비밀번호를 변경할 수있는 페이지에 대한 컨트롤러의Spring 3 주석 컨트롤러와 함께 2 개 이상의 Validator를 사용할 수 있습니까?

<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); 
    } 
    ... 
} 

는 봄 (3) 사이에 1 대 1 관계를 가정 컨트롤러 -을 양식 - WebDataBinder - 검사기. 5 개의 개별 유효성 검사기를 집계하는 복합 유효성 검사기를 만들고 Validator#supports()Validator#validate() 호출을 위임 할 수 있지만 실제로 가장 좋은 해결책입니까?

답변

1

이것은 오래된 문제였습니다.

여기에 코멘트를 추가 :

스프링 3.2.1.RELEASE 후, DataBinder#addValidators(Validator... validators) 사용할 수 있습니다.

+0

Spring Web MVC 2.x에서이 옵션을 다시 가져 왔음을 알려 줘서 고맙습니다. –

0

내가 생각할 수있는 최선의 해결책은 유효성 검사기 컬렉션을 삽입하고 직접 수동으로 스핀하는 것입니다. 그래서 지금 나는 내 컨트롤러 클래스에서 initBinder()을 제거하고 여기에 내가 추가 된 내용은 다음과 같습니다

<util:list id="accountSettingsValidators"> 
    <ref bean="emailFormatValidator" /> 
    <ref bean="uniqueEmailValidator" /> 
    <ref bean="changeEmailValidator" /> 
    <ref bean="passwordWithConfirmationValidator" /> 
    <ref bean="changePasswordValidator" /> 
</util:list> 
3

내가 생각하는 또 다른를 :

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 봄 설정에서, 내가 주입하는 유효성 검사기의 목록을 작성 ValidatorFacade를 가지고 차례로 다른 모든 유효성 검사기를 하나씩 호출하는 것이 었습니다. 그런 식으로 initBinder 및 ValidatorFacade를 주입 할 필요가 없습니다. FormBean이 자동으로 ValidatorFacade를 호출하고 모든 것이 자동으로 처리됩니다. 그냥 생각.

+0

[this] (https://github.com/hdiv/hdiv/wiki/Appendix-B%3A-Composite-validator-example-for-Spring-MVC)와 같은 의미입니까? 실제로이 온라인에 대한 몇 가지 다른 예를 발견 했으므로 내가가는 방법이라고 생각합니다. –

+0

예 .. 저는 xml 대신 봄의 autowire를 사용하여 다른 유효성 검사기를 주입하는 것을 선호하지만 아이디어는 같습니다. – raddykrish

관련 문제