[Spring] 스프링 상태유지 기술(쿠키, 세션)

지수·2021년 10월 6일
2

플레이데이터

목록 보기
44/50
post-thumbnail

http의 기본 특성 비연결성무상태성 때문에, 서버는 클라이언트를 기억하지 못한다.
하지만 웹을 개발하다보면 때때로 서버가 클라이언트를 기억해줘야하는 순간들이 필요하다..!

한 번 로그인을 하고 나면 해당 고객 로그인 정보를 기억한다던가,
로그인 하지 않고 장바구니에 넣었던 상품을 로그인 하면 다시 장바구니에 그대로 넣어준다던가 ...

위와 같은 상황을 처리하기 위해 웹에서 쿠키, 세션을 이용하여 상태를 유지(=클라이언트와 연결 유지)한다.

그렇다면, 기존 Servlet 기반 웹 개발이 아닌 Spring Framework를 사용하여 웹 개발을 하면,

쿠키, 세션을 사용한 상태유지 기술이 얼마나 편해질까!? 알아보자!

엄....새로운 애노테이션 + API 폭격으로 당장은 편함을 느끼지 못했...지만
익숙해지면 빠르고 효율적으로 코드 작성이 가능 할 것 같다.
나에 비해 스프링이 너무 똑똑한 탓..ㅎ😥


1. 쿠키

기존 servlet에서 쿠키에 저장된 값을 가져오려면,
Cookie[] cookieList = request.getCookies()와 같은 형식의 코드로
쿠키 전체 리스트를 가져와 반복문을 통해 찾고자하는 key 값을 가진 쿠키를 찾아내야했다.


그런데 스프링에서는,

쿠키값을 사용해야하는 메소드 내부에
@CookieValue("key") 애노테이션을 붙인 변수를 파라미터로 넘기면
스프링이 알아서 해당 키 값을 가진 쿠키 값을 변수에 할당해준다.

@RequestMapping("cookie")
public String cookieTest(@CookieValue("id") String idValue) {
	System.out.println("내가 찾던 키값이 id인 쿠키 : " + idValue);
    
	return "redirect:/showcookie.jsp";
}



2. 세션

1) 세션 저장

- HttpSession 객체 생성하여 저장

Servlet 기반으로 개발할 때와 마찬가지로 HttpSession 객체를 생성하여 세션에 데이터를 저장할 수 있다.

  • HttpSession session을 파라미터로 넘겨
  • session.setAttribute("key", value); 로 세션에 데이터 저장
@RequestMapping("httpsession")
public String sessionTest1(HttpSession session) {
	session.setAttribute("key1", "value1");
	session.setAttribute("key2", "value2");

	return "redirect:/showsession.jsp";
}

- Model 객체 생성하여 저장

Spring API인 Model 객체를 사용하여 세션에 데이터를 저장할 수 있다. (🍃이것이 보다 스프링스러운 개발 방법)

  • Model model을 파라미터로 넘겨
  • model.addAttribute("key", value); 로 데이터 저장
  • 세션에 등록하기 위해 @SessionAttribute({}) 에 키 값 등록 (아래 2)@SessionAttribute 참고)
@RequestMapping("model-session1")
public String sessionTest2(Model model) {
	model.addAttribute("key3", "value3");
	model.addAttribute("key4", "value4");

	return "redirect:/showsession.jsp";
}
  • query string으로 넘어 온 값이 특정 클래스 멤버 변수와 일치한다면,
    자동으로 해당 클래스 객체를 생성하여 세션에 저장하는 것도 가능하다.
//href="model-session2?id=geesuee&age=25"
//Customer 객체의 멤버 변수 id와 age가 query string으로 전달되어
//자동으로 Customer 객체 생성하여 parameter로 사용 가능
@RequestMapping("model-session2")
public String sessionTest2(Model model, Customer customer) {
	model.addAttribute("cust", customer);

	return "redirect:/showsession.jsp";
}

Model 객체를 생성하여 데이터를 저장하는 방법의 특징 : request와 session에 둘 다 저장된다.



2) @SessionAttribute

✅ Controller 클래스 선언구에 선언
Spring이 관리하도록 세션에 데이터를 저장하여 관리할 때, 위 애노테이션으로 key 값 등록
Spring API로 관리하는 Session

- @SessionAttribute에 (기존에 세션에 저장된) 데이터 키 값 등록

  • @SessionAttributes 애노테이션에 파라미터로 데이터 키 값 리스트 입력
  • 해당 리스트 안의 값을 키로 갖는 세션 데이터들을 Spring API로 관리
@Controller
@SessionAttributes({"key1", "key2", "key3", "key4"}) 
public class SubController {
...
}

- @SessionAttribute에 새로 생성한 데이터 키 값 등록

위 방식과 마찬가지로

  • Model 객체를 생성하여 `addAttribute("key", value)로 값을 저장하고
  • 해당 키 값을 @SessionAttribute 애노테이션이 받는 파라미터 내부 리스트에 추가


3) 세션 값 삭제

- HttpSession ⇒ invalidate(), removeAttribute("key")

HttpSession 객체를 생성하여 세션에 저장한 데이터의 경우(=@SessionAttribute에 등록하지 않은 경우),

  • HttpSession의 invalidate() 메소드를 통해 세션 데이터 일괄 삭제
  • 혹은 removeAttribute("key") 메소드를 통해 특정 키 값의 세션 데이터 삭제
@RequestMapping("sessionDelete1")
public String sessionDelete1(HttpSession session) {
	session.removeAttribute("key1"); //key1을 키 값으로 갖는 데이터만 삭제
	//session.invalidate(); //HttpSession으로 저장한 모든 세션값 삭제
  
	return "redirect:/showsession.jsp";
}

🔥 주의 : 위 두 가지 메소드로는 @SessionAttribute에 ⭕등록된⭕ 세션은 삭제할 수 없음



- @SessionAttribute ⇒ setComplete()

@SessionAttribute에 데이터 키 값을 등록하여, 스프링 API가 관리하는 세션 데이터로 설정한 경우,

  • SessionStatus 객체인 SessionStatus status 생성하여 파라미터로 넘기고
  • status.setComplete() 메소드를 통해 스프링 API 관리 세션 데이터 일괄 삭제
@RequestMapping("sessionDelete2")
public String sessionDelete2(SessionStatus status) {
	status.setComplete();
  
	return "redirect:/showsession.jsp";
}

🔥 주의 : 위 메소드로는 @SessionAttribute에 ❌등록되지 않은❌ 세션은 삭제할 수 없음



4) 세션 값 바인딩

- @ModelAttribute로 세션 값 찾아 변수에 할당

  • @ModelAttribute(key) String value를 파라미터로 넘기면
  • 스프링이 관리하는 세션 @SessionAttribute에서 해당 키 값을 가진 세션 데이터가 있는지 찾아서 바인딩
  • 메소드 내부에서 value(변수명)으로 해당 세션 값 사용 가능
  • String value = (String)session.getAttribute(key) 와 유사
@RequestMapping("/sessionBinding")
public String sessionBind(@ModelAttribute("key1") String v1, @ModelAttribute("key2") int v2) {
	System.out.println("key1 키 값으로 저장된 세션 데이터 : " + v1);
	System.out.println("key2 키 값으로 저장된 세션 데이터 : " + v2);
		
	return "redirect:/step03Session.jsp";
}
profile
사부작 사부작

0개의 댓글