[Spring] 어노테이션@ - RequestParam, ModelAttribute, SessionAttributes
♡이전 포스팅♡ 에서는 XML에 파일에 하였던 설정들을 Java 클래스 파일에 @을 사용하여
스프링 설정을 하였는데 이번 시간에는 더 다양한 @과, 속성들을 사용해보려고 한다.
1. Model 객체 사용
지금까지는 ModelAndView 커맨드 객체를 사용해서 mav를 output으로 보내었는데
스프링 부트 스타일이 string으로 정형화 되었기 때문에 output을 string으로 변경해보았다.
<변경 전 후 비교>
public class BoardController {
// ModelAndView 방식
@RequestMapping("/board.do")
public ModelAndView board2(BoardVO bVO, BoardDAO bDAO,HttpServletRequest request, ModelAndView mav) {
bVO=bDAO.selectOneBoard(bVO);
mav.addObject("data", bVO);
mav.setViewName("board.jsp");
return mav;
}
// Model방식
@RequestMapping("/board.do")
public String board(BoardVO bVO, BoardDAO bDAO,HttpServletRequest request, Model model) {
bVO.setBid(Integer.parseInt(request.getParameter("bid")));
bVO=bDAO.selectOneBoard(bVO);
model.addAttribute("data", bVO);
return "board.jsp";
}
}
Model
- 데이터만 저장
- model.addAttribute("변수명");
ModelAndView
- 데이터와 view를 같이 저장
- mav.addObject("변수명);
- mav.setViewName으로 이동하려는 View 저장
- return 타입은 ModelAndView
2. @RequestParam
- VO에 없는 값을 자동 세팅하기 위해서 사용 한다.
- jsp에서의 request.getParameter의 기능
- 필수 여부가 true이기 때문에 반드시 필요한 경우가 아니라면 required=false 설정이 필요하다.
- 보통 VO에 java에서만 사용되는 변수를 만들어서 사용하는 경우가 더 많고 , API나 VO가 제공되지 않을 때 사용하는 경우 사용된다 .
(value="뭘받을지 , defaultValue=디폴트값에 뭘 넣을지 , required= 필수인지 아닌지) 자료형 변수명
@RequestMapping("/main.do")//command 맴버변수로 search에 관련된게 없어서 검색조건, 검색어 자동 맵핑이 안됨
//-> 해결하기 위해서 자바에만 사용하기 위해 vo에 멤버변수로 추가한다.
//-> 다른 해결방법 : requestparam
public String main(@RequestParam(value="searchCondition",defaultValue="",required=false)String searchCondition,
@RequestParam(value="searchContent",defaultValue="",required=false)String searchContent, BoardVO bVO, BoardDAO bDAO,
@ModelAttribute("userId")MemberVO mVO,MemberDAO mDAO,HttpServletRequest request, Model model) {
if(searchCondition.equals("TITLE")) {
bVO.setTitle(searchContent);
}else if(searchCondition.equals("WRITER")) {
bVO.setWriter(searchContent);
}
mVO = mDAO.selectOneMember(mVO);
System.out.println("검색조건: "+searchCondition);
System.out.println("검색어: "+searchContent);
List<BoardVO> datas=bDAO.selectAllBoard(bVO);
model.addAttribute("datas", datas);
model.addAttribute("member", mVO);
System.out.println("main로그 :" + mVO);
return "main.jsp";
}
3. @ModelAttribute
사용 상황 ex)
view 작업자 입장에서 검색 기능이 있다는 회의를 진행
-> 검색할 공간을 확보해야겠다고 생각하고 제목/내용/작성자 등... 뷰작업자는 칼럼을 알아야 만들 수 있음
-> 뷰작업자는 뷰에서 칼럼까지 신경써야하나 의문점을 가지게됨!
이때! 컨트롤러 작업자가 뷰 작업자야 ~~ 신경쓰지마~~ 내가 값을 넘겨줄게!
이런 상황에서 사용하는게 @ModelAttribute
- View에서 사용할 데이터를 컨트롤러에서 설정하는 용도로 사용
- @RequestMapping 메서드보다 먼저 호출됨
- @ModelAttribute 메서드는 실행 이후에 객체를 반환하는데, 이 반환값을 Model에 자동저장됨
- Model에 자동저장되기때문에 View에서 사용가능하다!
검색 조건을 추가할 경우가 발생되기 때문에 이를 뷰작업자가 아닌 컨트롤러 작업자가 할 수 있도록
@ModelAttribute를 사용하여 설정한 데이터를 "scMap"이란 이름으로 뷰에서 출력할 수 있다.
@Controller
@SessionAttributes("data")
public class BoardController {
@ModelAttribute("scMap")//@RequestMapping메서드 보다 먼저 수행!!
public Map<String,String> searchConditionMap(){
//view에 어떤 검색조건을 보이게 할지 설정
Map<String,String> scMap =new HashMap<String,String>();
scMap.put("제목", "TITLE");
scMap.put("작성자", "WRITER");
return scMap; //해당 반환값으로 view에서 볼 수 있음
}
@RequestMapping("/main.do")
public String main(@RequestParam(value="searchCondition",defaultValue="",required=false)String searchCondition,@RequestParam(value="searchContent",defaultValue="",required=false)String searchContent, BoardVO bVO, BoardDAO bDAO,MemberVO mVO,MemberDAO mDAO, Model model) {
if(searchCondition.equals("TITLE")) {
bVO.setTitle(searchContent);
}else if(searchCondition.equals("WRITER")) {
bVO.setWriter(searchContent);
}
mVO = mDAO.selectOneMember(mVO);
//System.out.println("검색조건: "+searchCondition);
//System.out.println("검색어: "+searchContent);
List<BoardVO> datas=bDAO.selectAllBoard(bVO);
model.addAttribute("datas", datas);
return "main.jsp";
}
}
검색 폼 jsp
<!-- 검색 form -->
<form action="main.do" method="post">
<table>
<thead>
<tr>
<th><select name="searchCondition">
<c:forEach var="v" items="${scMap}">
<option value="${v.value}">${v.key}</option>
</c:forEach>
</select></th>
<th><input type="text" name="searchContent"
placeholder="검색어를 입력하세요..."></th>
<th><input type="submit" class="button" value="search"></th>
</tr>
</thead>
</table>
</form>
<!-- 검색 form -->
4 .@SessionAttribute
사용 상황 ex) 회원 정보를 수정하는 상황일 때 view에서 "name=null" 로 넘어올 경우에는
모든 데이터가 null 값으로 넘어오게 된다.
"NULL 업데이트 이슈"
View 작업자는 기능만 알고, 내부로직은 모름 때문에 (필요한 데이터인데) 전달되지않는 파라미터가 발생
전달되지않은 파라미터의 값은 null이 됨 , null 값이 업데이트 될수도있음
"NULL 업데이트 방지" 를 위해서 @SessionAttribute가 사용!
위 예시 상황인 기존에 name값이 존재한다면 기존 정보를 유지할 수 있도록 해야한다.
@Controller
@SessionAttributes("member")//member라는 정보가 Model에 add되면 session에 저장해라!!
public class MemberController {
@RequestMapping(value="/login.do",method=RequestMethod.GET)
public String index() {
return "login.jsp";
}
@RequestMapping(value="/login.do",method=RequestMethod.POST)
public String selectOneMember(MemberVO mVO,MemberDAO mDAO, HttpSession session, Model model) {
mVO=mDAO.selectOneMember(mVO);
if(mVO==null) {
return "redirect:login.jsp";
}
else {
model.addAttribute("member", mVO);//model에 "member"가 add!! -> session에 저장
return "main.do";
}
}
@RequestMapping("/update.do")
public String mypageupdate(@ModelAttribute("member")MemberVO mVO,MemberDAO mDAO) {
//원래 존재하던 member를 set해주고, 변경되는 정보는 그 뒤에 set!
mDAO.updateMember(mVO);
//만약 변경사항이 있다면 새로운 정보로 덮어씌워줌!
return "main.do";
}
}
로그인 후 회원 정보수정 부분
1) @SessionAttribute("member")를 상단에 선언하여 member라는 이름의 정보가 Model에 저장되면 session 저장해줘!
2) selectOneMember() 메서드를 통해서 model.addAttribute("member", mVO); session에 저장됨!
3) mypageupdate() @MA"member"를 설정하면, @SA에 의해서 저장되어있던 "member"가 저장되고,
그 뒤에 사용자가 변경한 내용이 덮어씌워지면서 null값을 방지하게 됨!!