@ModelAttribute 를 이용하면 2가지 작업이 가능

ㄱ. @RequestMapping 어노테이션이 적용되지 않은 별도 메소드로 모델에 추가될 객체를 생성가능
ㄴ. 커맨드 객체의 초기화 작업을 수행

두개의 RequestMapping 된 메소드가 같은 내용의 모델을 필요로 한다고 할때, 보통 그냥 별도의 메소드로 빼서 그것을 참조하게
한다. 

단 이렇게 하면 공통 메소드에 추가 조건절이 들어갈 수 도 있고 리턴에 대해서도 사용하는 측에서 맞춰야한다.

이때 @ModelAttribute를 사용할 수 있다.

 @ModelAttribute 를 메소드에 적용하면 해당 메소드가 생성한 객체가 뷰에 전달된다!!!!


아하.. 그래서 return 에 없는 객체들을 jsp 에서 참조가능했구나!!!!!!

즉 이 어노테이션은 ModelAttribute , 모델속성!! 이라는 의미의 단어를 그대로 뜻하는 것이다!!! 


@Controller
public class GameSearchController {
@Autowired
private SearchService searchService;

@ModelAttribute("searchTypeList")
public List<SearchType> referenceSearchTypeList() {
List<SearchType> options = new ArrayList<SearchType>();
options.add(new SearchType(1, "전체"));
options.add(new SearchType(2, "아이템"));
options.add(new SearchType(3, "캐릭터"));
return options;
}

@ModelAttribute("popularQueryList")
public String[] getPopularQueryList() {
return new String[] { "게임", "창천2", "위메이드" };
}

@RequestMapping("/search/main.do")
public String main() {
return "search/main";
}

@RequestMapping("/search/game.do")
public ModelAndView search(@ModelAttribute("command") SearchCommand command) {
ModelAndView mav = new ModelAndView("search/game");
System.out.println("검색어 = " + command.getQuery().toUpperCase());
SearchResult result = searchService.search(command);
mav.addObject("searchResult", result);
return mav;
}


해서 위의 콘트롤러를 보면 리턴해줄 모델의 값은 단지 mav일뿐이다. 허나 @ModelAttribute 어노테이션을 다른 메소드에 붙이므로써
모델에 속성을 추가하게 되는것이다!



다른 용도는 커맨드 객체 초기화 부분이다.
@ModelAttribute 어노테이션을 사용하면, 커맨드 객체의 초기화 작업을 수행할 수도 있다.
그럴수 밖에... 
@Controller
@RequestMapping("/account/create.do")
public class CreateAccountController {

@ModelAttribute("command")
public MemberInfo formBacking(HttpServletRequest request) {
if (request.getMethod().equalsIgnoreCase("GET")) {
MemberInfo mi = new MemberInfo();
Address address = new Address();
address.setZipcode(autoDetectZipcode(request.getRemoteAddr()));
mi.setAddress(address);
return mi;
} else {
return new MemberInfo();
}
}

private String autoDetectZipcode(String remoteAddr) {
return "000000";
}

@RequestMapping(method = RequestMethod.GET)
public String form() {
return "account/creationForm";
}

@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") MemberInfo memberInfo,
BindingResult result) {
new MemberInfoValidator().validate(memberInfo, result);
if (result.hasErrors()) {
return "account/creationForm";
}
return "account/created";
}
}

GET/POST 각각의 요청에 따라 객체 초기화가 가능하다.
위에서보면 submit 시의 command 가 바로 @ModelAttribute("command") 의 객체를 가르키게 된다.
왜냐면 @ModelAttribute 어노테이션이 적용된 메소드가 @RequestMapping 어노테이션이 적용된 메소드보다 먼저 호출되므로,
초기화 작업처럼 되는것이다.

그리고 ModelAttribute 어노테이션이 적용된 메소드는 RequestMapping 어노테이션이 적용된 메소드와 동일한 타입의 파라미터를 가질 수 있다.
 @ModelAttribute("command")
public MemberInfo formBacking(HttpServletRequest request) {

HttpServletRequest 말고도 Locale, @RequestParam 어노테이션 적용, @PathVariable 어노테이션등을 적용가능하다. 
 



'IT > 스프링' 카테고리의 다른 글

PathVariable 어노테이션을 이용한 URI 템플릿...  (0) 2012.01.16
URI 매칭.. (서블릿 맵핑)  (0) 2012.01.13
모델 생성.... (Model )  (0) 2012.01.13
@Controller 어노테이션... - 1 -  (0) 2012.01.10
filter....  (0) 2012.01.10

+ Recent posts