[spring]@SessionAttributes와 @SessionAttribute란?(장바구니, 회원가입 폼 예시)

2020년 10월 02일 by Xion

    [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을 활용후에는 SessionStatussetComplete() 메서드 를 활용하여 세션을 할당 해지 시켜줘야합니다.

( *그렇지 않으면 세션에 계속 남아있게 됩니다.)

 

예제를 살펴보겠습니다.

두 개로 나눠진 등록폼이 있다고 가정해봅시다.

 

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년차가 직접 겪은 국비지원 패스트캠퍼스 후기 보러가기

 

국비지원 패스트캠퍼스 후기 현직 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