@ModelAttribute가 Controller 메소드의 매개변수로 선언된 Command 객체의 긴 이름을 짦은 이름으로 변경할때도 사용되지만(해당 포스트는 여기를 클릭),
Controller 클래스에 있는 특정 데이터를 View(.jsp 페이지)에서 사용할수 있도록 View로 넘기는 용도로도 사용되는 별스런 역할도 할수 있다.
일단 개념부터 정리를 해 보면...

어떤 컨트롤러 클래스 안에있는 특정 메소드에 @ModelAttribute 어노테이션이 붙어 있으면 해당 컨트롤러 클래스의 모든 @RequestMapping 어노테이션이 붙은 메소드가 호출될 때마다 그 메소드 호출 전에 @ModelAttribute가 붙은 메소드가 일단 먼저 호출되고 그 이후 @RequestMapping이 붙은 메소드가 호출되는데 이때 @ModelAttribute 메소드 실행 결과로 리턴되는 객체(데이터)는 자동으로 @RequestMapping 어노테이션이 붙은 메소드의 Model에 저장이되고 그 이후에 .jsp(View)에서 @ModelAttribute 메소드가 반환한 데이터를 사용할수 있다. 
놀라운 @ModelAttribute의 능력이랄까?

일단 코드에서 확인해 보자. 아래와 같은 컨트롤러 클래스가 있다.

@Controller
public class BoardController {
	... 전 략 ...
	
	//글 수정
	@RequestMapping("/updateBoard.do")
	public String updateBoard(BoardVO vo, BoardDAO bdDao) throws Exception {
		System.out.println("UpdateBoardController 글 수정 처리~");
		
		bdDao.updateBoard(vo);
		return "getBoardList.do";
	}
	
	//글 상세 조회
	@RequestMapping("/getBoard.do")
	public String getBoard(BoardVO vo, BoardDAO bdDao, Model model) throws Exception {
		System.out.println("GetBoardController 글 상세 조회 처리~");
		
		model.addAttribute("boardModel", bdDao.getBoard(vo)); 
		return "getBoard.jsp";
	}
	
	//글 목록 검색
	@RequestMapping("/getBoardList.do")
	public String getBoardList(@RequestParam(value="searchCondition", defaultValue="TITLE", required=true) String condition,
								@RequestParam(value="searchKeyword", defaultValue="", required=false) String keyWord,
								BoardVO vo, 
								BoardDAO bdDao, 
								Model model) throws Exception {
		System.out.println("$$$$$$$ GetBoardListController 글 목록 검색 처리~");
		
		model.addAttribute("boardListModel", bdDao.getBoardList(vo));
		return "getBoardList.jsp";
	}
	
	@ModelAttribute("myModelAttribute")
	public Map<String, String> joe() {
		System.out.println("▶▶▶▶▶▶▶ 여기는 joe()~~~ ▶▶▶▶▶▶▶");
		
		Map<String, String> infoMap = new HashMap<String, String>();
		
		infoMap.put("joe", "Web Developer");
		infoMap.put("kim", "Designer");
		infoMap.put("nana", "CEO of M&P");
		
		return infoMap;
	}
}

위의 BoardController 클래스안에는 @RequestMapping 어노테이션이 붙은 메소드가 3개가 있는데
-. public String updateBoard()
-. public String getBoard()
-. public String getBoardList()

이들 메소드가 호출될때마다 @ModelAttribute("myModelAttribute") 어노테이션이 붙은 아래 메소드가 먼저 호출된다.
public Map<String, String> joe()
그리고 joe() 메소드에서 반환하는 데이터(infoMap)가 클라이언트 요청으로 실행될 @RequestMapping이 붙은 메소드의 Model 객체에 자동으로 저장이 된다. 이렇게 저장된 데이터는 .jsp 페이지에서 사용할수 있게 되는데 이때 @ModelAttribute("myModelAttribute") 안에 지정한 문자열인 myModelAttribute가 객체 이름이 된다. 
역시 .jsp에서 어떻게 데이터에 접근하는지 코드에서 확인해 보자.

예를들어 http://xxx.xxx.xx/getBoard.do로 요청이 들어오면 먼저 
public Map<String, String> joe()가 먼저 호출이 되고 그 이후
public String getBoard(BoardVO vo, BoardDAO bdDao, Model model)가 호출이 되는데 이때 joe() 메소드에서 생성된 infoMap 데이터가 getBoard()의 model 객체에 자동으로 저장이 되고 getBoard.jsp에서는 다음과 같이 데이테어 접근할수 있게 된다.

... 전 략 ...
	<h1>글 상세보기</h1>
	<a href="logout.do">로그아웃</a>
	<hr>
	
	구성원1 : ${ myModelAttribute.joe }<br/>
	구성원2 : ${ myModelAttribute.nana }<br/>
	<hr/>
... 후 략 ...

위 .jsp 페이지의 출력 결과는 다음과 같이 될 것이다.

구성원1 : Web Devloper 
구성원2 : CEO of  M&P 

혹은 다음과 같이도 할수 있다.

	<c:forEach items="${ myModelAttribute }" var="item">
		item.key : ${item.key }<br/>
		item.value : ${item.value }<br/><br/>
	</c:forEach>
	<hr/>


그러면 다음과 같은 결과가 나올 것이다.

item.key : joe
item.value : Web Developer

item.key : nana
item.value : CEO of M&P

item.key : kim
item.value : Designer

@ModelAttribute 어노테이션이 이런 용도로도 사용될수 있다는 점이다. 
그런데 @ModelAttribute는 이것 외에 또 있으니 @SessionAttribute와 연결되면 또 요술을 부린다.

+ Recent posts