DEV Community

HEEAH IM
HEEAH IM

Posted on

Model Binding : WebDataBinder, @InitBinder

Model Binding

@ModelAttribute, @RequestParam, @PathVariable 등을 지정된 파라리터를 @Controller 에 추가하면 다음과 같은 작업이 자동으로 진행된다.

1. 파라미터 타입의 object를 만든다.
@ModelAttribute User user라는 파라미터를 선언했다면 User 타입의 Object를 생성한다. @SessionAttributes에 의해 세션에 저장된 model object가 있다면 그걸 가져온다.
2. model object의 property에 웹 파라미터를 바인딩해준다.
http를 통해 전달되는 파라미터는 기본적으로 문자열로 되어 있다. Spring의 기본 PropertyEditor를 이용해서 http 파라미터 값을 model의 property type에 맞게 전환한다. 실패시, BindingResult 오브젝트 안에 바인딩 오류를 저장하여 예외를 발생시킨다.
(PropertyEditor은 Spring이 제공하는 DataBinder 인터페이스를 통해 사용된다.)
3. model 값을 검증한다.
이전 단계에서 타입에 대한 검증은 끝났으나 그 외의 검증할 내용이 있다면 적절한 validator를 등록해서 검증할 수 있다.

WebDataBinder

AnnotationMethodHandlerAdapter는 @ModelAttribute 등처럼 http요청을 파라미터 변수에 바인딩해주는 작업이 필요한 애노테이션을 만나면 먼저 WebDataBinder를 만든다.
WebDataBinder는 여러 기능을 제공하는데 그 중 http요청으로부터 가져온 문자열을 파라미터 타입의 Object로 변환하는 기능이 있다. 이런 변환 작업은 위에서 언급되었던 PropertyEditor를 이용한다. 따라서 개발자가 직접 만든 커스텀된 PropertyEditor를 적용하려면 WebDataBinder에 등록해줘야 한다. 이 때 필요한게 @InitBinder이다.

@InitBinder

WebDataBinder를 초기화해주는 어노테이션이다. InitBinder()는 메소드 파라미터를 바인딩하기전에 자동으로 호출된다. 커스텀한 PropertyEditor, Validator 등을 적용되게 해준다.
아래는 validator를 @InitBinder를 통해 적용한 소스이다.

[AS-IS]

    private final SignUpFormValidator signUpFormValidator;

    @PostMapping("/signup")
    public String signUpSubmit(@Valid SignUpForm signUpForm, Errors errors) {
        if(errors.hasErrors()){
            return "account/signup";
        }
        signUpFormValidator.validate(signUpForm, errors);
        if(errors.hasErrors()){
            return "account/signup";
        }
        ....
        return "account/signupSuccess";
    }
Enter fullscreen mode Exit fullscreen mode

[TO-BE]

   private final SignUpFormValidator signUpFormValidator; 

    //form 객체 이름은 변수명이 아니라 type의 camel case를 따라간다.(변수명 바뀌어도 적용된다.삽질 NO)
    @InitBinder("signUpForm")
    public void initBinder(WebDataBinder webDataBinder){
        webDataBinder.addValidators(signUpFormValidator);
    }

    @PostMapping("/signup")
    public String signUpSubmit(@Valid SignUpForm signUpForm, Errors errors) {
        if(errors.hasErrors()){
            return "account/signup";
        }
        ....
        return "account/signupSuccess";
    }
Enter fullscreen mode Exit fullscreen mode

* 참고자료
토비의 스프링 Vol. 2 스프링의 기술과 선택
백기선 인프런 강의..

Top comments (0)