@ModelAttribute 를 이용하면 2가지 작업이 가능
1. @RequestMapping 어노테이션이 적용되지 않은 별도 메소드로 모델에 추가될 객체를 생성가능
2. 커맨드 객체의 초기화 작업을 수행
두개의 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 어노테이션등을 적용가능하다.
'# 웹 개발 > 프레임워크' 카테고리의 다른 글
sencha architect - 2.layout과 flex 개념잡기 (0) | 2013.07.18 |
---|---|
sencha architect - 1. 아키텍트 시작하기 (0) | 2013.07.17 |
spring dispatcher(name)-servlet.xml 설정하기 (0) | 2013.06.08 |
spring mvc web.xml 설정방법 (0) | 2013.06.08 |
spring injection 방법 (2) | 2013.06.08 |