@ModelAttribute
@ModelAttribute의 속성은 아래와 같다.
이름 | 타입 | 설명 |
---|---|---|
value | String | 바인드하려는 Model 속성 이름. |
@ModelAttribute는 실제적으로 ModelMap.addAttribute와 같은 기능을 발휘하는데, Controller에서 2가지 방법으로 사용된다.
1.메소드 리턴 데이터와 Model 속성(attribute)의 바인딩.
메소드에서 비지니스 로직(DB 처리같은)을 처리한 후 결과 데이터를 ModelMap 객체에 저장하는 로직은 일반적으로 자주 발생한다.
... @RequestMapping(value = "/updateDepartment.do", method = RequestMethod.GET) public String formBackingObject(@RequestParam("deptid") String deptid, ModelMap model) { Department department = departmentService.getDepartmentInfoById(deptid); //DB에서 부서정보 데이터를 가져온다. model.addAttribute("department", department); //데이터를 모델 객체에 저장한다. return "modifydepartment"; } ...
@ModelAttribute를 메소드에 선언하면 해당 메소드의 리턴 데이터가 ModelMap 객체에 저장된다.
위 코드를 아래와 같이 변경할수 있는데, 사용자로 부터 GET방식의 /updateDepartment.do 호출이 들어오면,
formBackingObject 메소드가 실행 되기 전에 DefaultAnnotationHandlerMapping이 org.springframework.web.bind.annotation.support.HandlerMethodInvoker을 이용해서
(@ModelAttribute가 선언된)getEmployeeInfo를 실행하고, 결과를 ModelMap객체에 저장한다.
결과적으로 getEmployeeInfo 메소드는 ModelMap.addAttribute(“department”, departmentService.getDepartmentInfoById(…)) 작업을 하게 되는것이다.
... @RequestMapping(value = "/updateDepartment.do", method = RequestMethod.GET) public String formBackingObject() { return "modifydepartment"; } @ModelAttribute("department") public Department getEmployeeInfo(@RequestParam("deptid") String deptid){ return departmentService.getDepartmentInfoById(deptid); //DB에서 부서정보 데이터를 가져온다. } 또는 public @ModelAttribute("department") Department getDepartmentInfoById(@RequestParam("deptid") String deptid){ return departmentService.getDepartmentInfoById(deptid); } ...
2.메소드 파라미터와 Model 속성(attribute)의 바인딩.
@ModelAttribute는 ModelMap 객체의 특정 속성(attribute) 메소드의 파라미터와 바인딩 할때도 사용될수 있다.
아래와 같이 메소드의 파라미터에 ”@ModelAttribute(“department”) Department department” 선언하면 department에는 (Department)ModelMap.get(“department”) 값이 바인딩된다.
따라서, 아래와 같은 코드라면 formBackingObject 메소드 파라미터 department에는 getDepartmentInfo 메소드가 ModelMap 객체에 저장한 Department 데이터가 들어 있다.
... @RequestMapping(value = "/updateDepartment.do", method = RequestMethod.GET) public String formBackingObject(@ModelAttribute("department") Department department) { //department에는 getDepartmentInfo에서 구해온 데이터들이 들어가 있다. System.out.println(employee.getEmployeeid()); System.out.println(employee.getName()); return "modifydepartment"; } @ModelAttribute("department") public Department getDepartmentInfo(@RequestParam("deptid") String deptid){ return departmentService.getDepartmentInfoById(deptid); //DB에서 부서정보 데이터를 가져온다. } ...
employee.getEmployeeid()가 아닌 department.getEmployeeid()가 아닌가 싶다.
===================================================================================
- @ModelAttribute
HTTP Request에 포함된 파라미터를 Model 객체로 바인딩함, @ModelAttribute의 'name'으로 정의한 Model객체를 다음 View에서 사용 가능
@ModelAttribute
@ModelAttribute는 컨트롤러에서 다음과 같이 두 가지 방법으로 사용할 수 있다.- 컨트롤러 메소드에 정의
- 컨트롤러 메소드의 입력 argument에 정의
입력 폼 페이지에서 출력해 줄 reference data를 전달하고자 할 때.
SimpleFormController의 referenceData() 메소드와 같은 역할
메소드의 argument로 입력된 Command 객체에 이름을 부여하고자 할 때.
@Controller @RequestMapping("/user.do") public class EditUserController { // 컨트롤러 메소드에 정의 @ModelAttribute("deptList") public List populateDeptList() throws Exception { return deptService.getDeptList(); } @RequestMapping(params = "param=add") public String addUser(@ModelAttribute("user") User user, BindingResult result, SessionStatus status) throws Exception { ...중략... } }
===================================================================================
Q > controller 단에서, 예를 들면 아래 인자값 3개의 차이점을 알고 싶습니다.
3개 모두가 같은 의미인것 같은데...
BbsVO selectBbs(
BbsVO bbsVO,
@ModelAttribute("bbsVO") BbsVO bbsVO,
@RequestParam(value="bbsVO") BbsVO bbsVO,
)throws Exception{}
A >
우선 첫번째의 경우와 두번째의 경우 모두.. 앞 request parameter들이 VO에 담기는 역할은 똑같습니다..
다만, 두번째의 경우는 @ModelAttribute에 지정된 이름으로 모델 정보에 담아지기 때문에
View부분(보통 JSP)에서 bbsVO라는 모델이름으로 해당 VO 값들을 참조할 수 있습니다...
세번째의 경우는 bbsVO라는 request parameter를 BbsVO에 넣으라는 의미로.. 위 두개의 의미와 차이가 있으며..
하나의 값을 일반적인 VO에 넣을 수 없기 때문에.. 잘못된 형식입니다..
정리하자면.. 두번째 형식을 사용하시면 됩니다.
Q > 아래 소스를 비교해 주셨으면 합니다.
@RequestMapping("/sample/addSampleView.do")
public String addSampleView(@ModelAttribute("searchVO") SampleDefaultVO searchVO, Model model)throws Exception {
model.addAttribute("sampleVO", new SampleVO());
return "sample/egovSampleRegister";
}
---->
@RequestMapping("/sample/addSampleView.do")
public String addSampleView(SampleDefaultVO searchVO, Model model)throws Exception {
model.addAttribute("sampleVO", new SampleVO());
return "sample/egovSampleRegister";
}
이렇게 하는 것의 차이점을 알고 싶습니다. 의미상으로는 같은 건가요?
A >
@ModelAttribute를 사용하는 이유는 Model 속성(VO)과 메소드 파라미터의 바인딩을 위해서입니다.
즉, serchVO에 웹 request parameter값을 넣으려면 @ModelAttribute를 지정하셔야 합니다.
다만, 실제 @ModelAttribute 없이 테스트를 하셔도 parameter값들은 들어가도록 되어 있습니다.
(Spec.상의 설명과 DispatcherServlet 구현상의 차이인 것 같습니다.)
다시 말씀드리면 위 경우만으로 보면 차이점이 없습니다.
그러나 다음 JSP인 egovSampleRegister.jsp에서 serchVO 값을 참조하려면 반드시 @ModelAttribute를 지정하셔야 합니다.
@ModelAttribute에 지정된 name으로 JSP 페이지에서 참조할 할 수 있도록 Model정보로 담겨지기 때문입니다.
(별도로 두번째 방식에서 model.attribute("searchVO", searchVO); 코드를 추가하셔도 같은 기능을 수행합니다.)
Q> jsp 내의 <% %> 안에서 db에서 가져온 값을 사용하는 방법
A>
Controller에서 담겨진 model 정보는 request 상의 attribute로 jsp에 전달됩니다.
즉 jsp 서버 사이드 스크립트(<% ... %>)에서는 다음과 같은 형식으로 사용하실 수 있습니다.
<%
DataVO data = (DataVO)request.getAttriubte("data");
%>
Q> db에 저장된 테그 표시
A> <c:out value="${....}" escapeXml="false" />
Q> 오라클 10g clob 등록방법
A>
조회는 resultmap에 clob로 선언을 해주어 표시를 했습니다.
저장은 #contents:CLOB# 이런 방법으로 저장함.
Q > DB resource
egovframework/spring/context-datasource.xml
./WEB-INF/classes/egovframework/spring/context-datasource.xml
ex)
@Controller
@RequestMapping("/annot/registMember.do")
@SessionAttributes("memberInfo") //세션에 저장할 모델 객체
public class RegistMemberAnnotController {
private Validator validator = new MemberInfoValidator();
@ModelAttribute("memberInfo") // 스프링은 memberInfo를 뷰에 전달한다.
public MemberInfo formBacking(HttpServletRequest reqeust) {
MemberInfo memberInfo = new MemberInfo();
memberInfo.setAddress(new Address());
return memberInfo;
}
@RequestMapping(method = RequestMethod.GET)
public String showForm() {
return "registMemberFormUseAnnot";
}
@RequestMapping(method = RequestMethod.POST)
public String processSubmitForm(@ModelAttribute("memberInfo") //ModelAttribute를 이용하여 커맨드 객체의 이름을 준다.
MemberInfo command, BindingResult errors, SessionStatus sessionStatus) {
validator.validate(command, errors);
if (errors.hasErrors()) {
return showForm();
}
// 로직 처리
sessionStatus.setComplete(); //세션에 적용된 모델 객체를 삭제할 때 사용
return "registMember";
}
}
'Framework & Platform > Spring' 카테고리의 다른 글
Spring - Validation (0) | 2012.05.21 |
---|---|
spring - Validator (0) | 2012.05.21 |
Spring - @RequestParam (0) | 2012.05.21 |
Spring - ModelAndView (0) | 2012.05.21 |
Spring - contextConfigLocation (0) | 2012.05.16 |