- [spring]@SessionAttributes와 @SessionAttribute란?(장바구니, 회원가입 폼 예시) 목차
| @SessionAttributes란?
모델(Model) 정보를 HTTP 세션에 저장해주는 애노테이션입니다.
- HttpSession을 직접 사용할 수도 있지만
- 이 애노테이션에 설정한 이름에 해당하는 모델 정보를 자동으로 세션에 넣어줍니다.
- @ModelAttribute는 세션에 있는 데이터도 바인딩합니다.
- 여러 화면(또는 요청)에서 사용해야 하는 객체를 공유할 때 사용합니다.
ex) 장바구니, 여러 화면에 걸쳐 나눠진 회원가입 등
또한 @SessionAttributes를 사용하면 @ModelAttribute OR model.addAttribute()를 활용하여 객체를 저장할 경우
세션에 저장이 되도록 지정할 수 있습니다.
( * 이러한 경우에는 세션이 제거되거나 SessionStatus 객체를 사용하여 명시적으로 지울때까지 동일한 세션에는 계속 사용할 수 있습니다.)
장점
-직접 세션 객체에 (setAttribute(), getAttribute() 메서드를 사용하여 작업을 할 수 있지만, @ModelAttribute가 세션에 객체를 저장하고, 찾도록 한정할 수 있다는 장점이 있습니다.
또한 @ModelAttribute와 같이 사용해서 세션 객체에 넣고 빼는 작업을 숨겨주고 스프링 form 태그와 연동되어 폼에 값을 넣는 작업도 단순화 되는 장점이 있습니다.)
SessionAttributes활용
@Controller
@SesstionAttributes("test") //SessionAttribute 사용 보통 sessionStatus와 함께 사용한다
public class ExampleController {
@GetMapping("/events")
//SessionStatus를 활용
public String createEvent(@Validated @ModelAttribute Person person,SessionStatus sessionStatus){
Persion person = new Persoon();
person.setName = ("gd");
model.addAttribute("person",person);
sessionStatus.setComplete(); //해당 페이지에서 저장된 세션 값 초기화(완성)
return "/person/form";
}
}
@SessionAttribute 사용 시 주의할 점
위의 예시와 같이 Session을 활용후에는 SessionStatus의 setComplete() 메서드 를 활용하여 세션을 할당 해지 시켜줘야합니다.
( *그렇지 않으면 세션에 계속 남아있게 됩니다.)
예제를 살펴보겠습니다.
두 개로 나눠진 등록폼이 있다고 가정해봅시다.
1.컨트롤러에서 @SessionAttributes를 지정합니다.
@Controller
@SessionAttributes({"test","testValue"})
public class testController {
...
}
Model 객체에 저장시 세션에 저장될 key값을 지정합니다.
"test"는 등록폼과 수정에서 사용할 key값이고 "testValue" 는 상세보기에서 사용할 key 값 입니다.
같은 키값을 상세보기와 입력해서 사용하면 상세보기후에 등록폼으로 가면 조회 했던 내용이 폼에 미리 보여지게 됩니다. ( 그러므로 분리 )
2.등록 form Controller
@RequestMapping(value="/test_insert.do", method=RequestMethod.GET)
public String test_insertDo("ModelAttribute("test") TestVo test, Model model){
return "test_insert";
}
- ModelAttribute("test")로 지정하면 세션에 "test"를 key로 session에서 객체를 찾게 됩니다.
등록폼을 최초 호출 시 다음과 같은 에러가 발생합니다 . 이유는 session에서 test로 객체를 찾지 못했기 때문입니다.
org.springframework.web.HttpSessionRequiredException: Expected session attribute 'test'
Model 객체에 직접 빈 객체를 생성, 추가해서 해결 할 수 있지만,
이전으로 되돌아 왔을때 초기화 되어 버리게 됩니다.
// 등록폼 첫페이지에 이 코드가 있으면 이전으로 돌아올때 초기화 되어 버린다.
model.addAttribute("test", new TestVo());
@ModelAttribute("test")
public TestVO setEmptyTest() {
return new TestVO();
}
컨트롤러에 @ModelAttribute 어노테이션은 메서드에 적용한 빈 TestVO객체를 반환하는 메소드를 추가함으로 해결할 수 있습니다.
2번째 방법으로는 최초의 등록폼을 호출을 GET / POST 방식으로 나눠 GET방식의 호출에서는
GET : model.addAttribute("test",new TestVO() ); 를 이용하고
POST : @ModelAttribute("test")를 사용할 수 있습니다.
단, "이전" 버튼으로 돌아올 때 현재 입력한 값이 적용되어야 하므로 POST방식을 사용해야 합니다.
@RequestMapping(value = "/test_insert.do", method = RequestMethod.GET)
public String test_insertDo(Model model) {
model.addAttribute("test", new TestVO());
return "test_insert";
}
@RequestMapping(value = "/test_insert.do", method = RequestMethod.POST)
public String test_insertDo2(@ModelAttribute("test") TestVo test, Model model) {
return "test_insert";
}
두 번째 form 입니다.
->첫 번째 form에서 "다음"버튼을 누르면 입력한 값들이 POST되고, 자동으로 TestVO 객체에 매Mapping 되어집니다.
Mapping에 사용된 객체는 세션에서 찾아서 사용됩니다.
@RequestMapping(value = "testNextInsert.do", method = RequestMethod.POST)
public String testNextInsert(@ModelAttribute("test") TestVo test, Model model) {
return "test_nextform";
}
입력이 성공하면, SessionStatus 객체의 setComplete() 메서드로 세션에서 지웁니다.
@RequestMapping(value = "/test_register.do", method = RequestMethod.POST)
public String testRegister(@ModelAttribute("test") TestVO test, SessionStatus sessionStatus, Model model) throws Exception {
// 서비스단 등록.
testService.register(test);
// 세션에서 초기화(지움).
sessionStatus.setComplete();
return "redirect:/test_list.do";
}
이제는 수정form을 살펴보겠습니다.
- 상세보기에서 조회된 정보를 세션에 저장해두고, 수정폼에서는 key값을 제외한 실제 수정될 수 있는 값만을 폼에서 보여줍니다.
상세보기
@RequestMapping(value = "/test_detail.do", method = RequestMethod.GET)
//매개변수로 bunho값을 받아옵니다.
public String testDetail(String bunho, Model model) throws Exception {
//bunho값으로 값을 조회하여 testDetail이라는 key값으로 model에 추가해줍니다.
model.addAttribute("testDetail", testService.selectBunho(bubho));
return "test_detail";
}
->Controller에 @SessionAttribute("testDetail")로 지정해 두면 @ModelAttribute("testDetail")뿐만 아니라
model.addAttribute("testDetail", obj); 역시 세션에 저장됩니다.
상세보기- 수정폼
- 일반적으로 수정폼에서 key값을 받아서 조회 후 보여주지만 여기서는 상세보기에서 세션에 저장된 값을 보여줍니다.
@RequestMapping(value = "/test_updateform.do", method = RequestMethod.GET)
//ModelAttribute를 이용하여 key값인 testDetail을 TestVo 객체로 매핑하여 가져옵니다.
public String testUpdateform(@ModelAttribute("testeDetail") TestVo test, Model model) throws Exception {
return "test_updateform";
}
상세보기 -수정하기
- 수정폼에는 key값이 존재하지 않지만 폼이 제출되면 세션에 저장되어 있던 test객체에 수정된 내용이 변경되고
기존의 키값을 그대로 유지한 채 값이 매핑되어 집니다.
@RequestMapping(value = "/test_update.do", method = RequestMethod.POST)
public String testUpdate(@ModelAttribute("testDetail") TestVO test, SessionStatus sessionStatus, Model model) throws Exception {
// 수정한다.
testService.updateTest(test);
// 세션에서 지운다.
sessionStatus.setComplete();
return "redirect:/test_list.do";
}
| @SessionAttribute란?
@SessionAttributes와는 성격이 정반대인 어노테이션입니다 !
실시간 베스트 글
혹시 국비지원이나 사설학원 (패스트 캠퍼스 등) 다니는 중이신가요?
현직 5년차가 직접 겪은 국비지원 패스트캠퍼스 후기 보러가기
'Spring' 카테고리의 다른 글
[Spring]@InitBinder란? (0) | 2020.10.10 |
---|---|
[Spring]Custom Annotation(커스텀 애노테이션) (0) | 2020.09.30 |
[spring]RestTemplate란? (0) | 2020.08.13 |
[springSecurity]스프링 시큐리티 (0) | 2020.08.08 |
[springSecurity]스프링 시큐리티 (0) | 2020.08.08 |