@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와 연결되면 또 요술을 부린다.
'Spring MVC' 카테고리의 다른 글
@SessionAttribute와 @ModelAttribute가 연동 될때의 동작 원리와 Command 객체의 동작원리 (1) | 2020.01.08 |
---|---|
Spring의 classpath:의 경로 위치 (6) | 2020.01.02 |
컨트롤러 클래스에서의 return이 갖는 의미 (0) | 2019.12.23 |
ModelAndView의 setViewName() 메소드에 redirect: 사용하는 법 (0) | 2019.12.20 |
AOP around의 proceed() 메소드 동작에 대한 개념 정리 (0) | 2019.12.11 |