--- tags: ModelAttribute --- @ModelAttribute 3부 - 메소드 @ModelAttribute === ## 메소드 @ModelAttribute 아래와 같이 유저 등록 폼을 응답하는 컨트롤러가 있다고 가정하자. ```java @Controller // 이번에는 등록폼이라서 @ResetController 대신 @Controller 로 설명 public class UserController { // 메소드 @ModelAttribute @ModelAttribute("defaultUser") public User defaultUser(){ return new User("아이디", 33, Gender.MALE); } // 등록 폼 @GetMapping("/user/regist") public String userRegistForm(@ModelAttribute("defaultUser") @Valid User user){ log.info("user : " + user); return "/user/regist"; } } ``` 컨트롤러 메소드에 인자로 전달되는 @ModelAttribute 객체의 생성 순서는 1부에서 다음과 같다고 했다. 1. 모델객체 생성 // new User() 2. 프로퍼티 바인딩 // setName(), setAge().. 3. 검증 userRegistForm() 에서 user 인자를 사용 하는것은 `model.getAttribute("user")` 를 사용 하는것과 같은것 이고, 1번 과정 에서 `model.addAttribute("user",new User())` 를 해 놨기 때문에 가능한 것 이라고 1부 에서 얘기 했었다. 그런데 이번 코드는 1부 코드에서 추가로 `메소드 @ModelAttribute` 영역이 추가 되었다. `메소드 @ModelAttribute` 는 어떤 역할을 할까? ## 메소드 @ModelAttribute 의 역할 ### 디폴트 모델 객체를 생성한다 만약 `메소드 @ModelAttribute` 가 없으면 `new User()` 로 객체를 생성 하지만, 있다면 `메소드 @ModelAttribute` 에서 만들어진 모델 객체를 참조 한다. 즉 위 코드의 로그 에서는 아무런 파라미터가 없어도 다음과 같은 로그를 보게 된다. ``` User(name=아이디, age=33, gender=MALE) ``` ### 디폴트 모델 객체 사용 예 등록폼에서 유저에게 기본값을 제공할 경우 쓸수 있다. 예를들어 남자/여자 중 남자로 선택하게 하거나, 전화번호 맨 앞자리 010 을 추가해서 디폴트 모델을 구성 해 놓으면, 등록폼에서는 기본값을 이용해 폼을 구성할수 있게 된다. --- ## 퀴즈 등록페이지를 주로 찾는게 남자여서 기본값을 남자로 설정하긴 했지만, 등록할땐 여자로 등록 할수도 있을 것 이다. 마침 여자 유저가 라디오버튼을 여자로 바꿔서 Gender.FEMALE 로 서브밋을 했다고 가정하자. 이때 userRegistForm() 메소드에서 받아보는 user 객체의 Gender 는 defaultUser() 가 생성해준 MALE 일까? 아니면 유저가 보낸 FEMALE 일까? ``` 보기 1. User(name=아이디, age=33, gender=MALE) 2. User(name=아이디, age=33, gender=FEMALE) ``` > 답을 예상 해보자. 1부를 잘 이해 했다면 맞출수 있다. ### 정답 `1.객체 생성` 과정에서 물론 MALE 로 설정된다. 하지만 `2.프로퍼티 바인딩` 과정을 거쳐 Gender.FEMALE 이 setter()주입 또는 리플렉션 을 통해 필드에 write 된다. 따라서 FEMALE 이 찍히게 된다. 리액션의 ConsultController 는 RestController 이긴 하지만 `메소드 @ModelAttribute` 를 작성 한 부분이 있다. 한번 구경 해보는것도 좋다.