[Spring] 스프링 세션, 쿠키 구현(Spring Session, Cookie)
| 세션과 쿠키(Session, Cookie)
웹 서비스는 HTTP 프로토콜을 기반으로 사용자와 통신한다. HTTP 프로토콜은 클라이언트와 서버와의 관계를 유지하지 않는 특징인 Stateless 기반인 프로토콜이다.
따라서 만약 쇼핑몰같은 웹서비스를 이용할 때 만약 HTTP 프로토콜만으로 통신한다면 페이지를 이동할 때마다 계속해서 서버와 연결해야하는 불편함이 생긴다. 또한 사용자의 요청마다 서버와 매번 새로운 연결이 생기기 때문에 로그인 상태유지, 장바구니 등의 기능을 구현하는 것이 매우 까다로워진다.
이런 Stateless 상태를 해결하는 두 가지 방식이 있는데 세션(Session)과 쿠키(Cookie)다. 두 방식 모두 사용자와 서버의 연결 상태를 유지해주는 방법으로, 세션은 서버에서 연결 정보를 관리하는 반면 쿠키는 사용자에 측에서 연결 정보를 관리하는 데 차이가 있다.
| 세션(Session)을 구현하기 위한 HttpServletRequest 사용
스프링 MVC에서 세션은 HttpServletRequest 혹은 HttpSession을사용해서 구현할 수 있다. 여기서는 HttpServletRequest를 통한 세션 생성방법을 알아보겠다.
@RequestMapping(value = "/modify", method = RequestMethod.POST)
public ModelAndView modify(Member member, HttpServletRequest request) {
HttpSession session = request.getSession();
Member mem = service.memberModify(member);
session.setAttribute("member", mem);
ModelAndView mav = new ModelAndView();
mav.addObject("memAft", mem);
mav.setViewName("/member/modifyOk");
return mav;
}
사용자 정보를 변경하는 요청인 /modify으로 요청이 들어오면 HttpServletRequest 객체인 request가 인자로 들어오면서 modify 메서드가 실행된다.
이 때 세션에 setAttribute 메서드를 통해 세션의 속성값을 설정한다. 이 속성값은 세션에 의해 유지되며 getAttribute 메서드를 통해 다른 요청을 처리하는 컨트롤러 메서드에서 이 값을 얻을 수 있다.
@RequestMapping(value = "/modifyForm", method = RequestMethod.GET)
public ModelAndView modifyForm(HttpServletRequest request) {
HttpSession session = request.getSession();
Member member = (Member) session.getAttribute("member");
ModelAndView mav = new ModelAndView();
mav.addObject("member", service.memberSearch(member));
mav.setViewName("/member/modifyForm");
return mav;
}
getSession 메서드를 통한 HttpSession 객체를 하나 생성하여 간단히 세션을 구하고 이 세션이 붙들고 있는 속성값을 얻을 수 있다. 이후에 /modifyForm 요청이 들어오면 사용자의 정보를 기억하고 그 결과를 JSP파일로서 반환하게 된다.
사용자의 세션을 끊고 싶으면 아래와 같은 방식으로 세션을 삭제하면 된다.
@RequestMapping(value = "/remove", method = RequestMethod.POST)
public String memRemove(Member member, HttpServletRequest request) {
service.memberRemove(member);
HttpSession session = request.getSession();
session.invalidate();
return "/member/removeOk";
}
/remove는 로그아웃을 하라는 요청을 나타내는 url이다. request 객체의 세션을 얻은 후 그 세션을 invalidate 메서드로 비활성화 시키면 세션이 끊긴다(로그아웃 됨). 이때부터 웹사이트에 연결이 되도 새로운 사용자 정보를 통해 로그인을 해야한다.
| 쿠키(Cookie)를 구현하기 위한 Cookie 객체 생성 및 @CookieValue 어노테이션
스프링 MVC에서 쿠키를 생성하는 방법은 다음과 같다.
public class Mall {
private String gender;
private boolean cookieDel;
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public boolean isCookieDel() {
return cookieDel;
}
public void setCookieDel(boolean cookieDel) {
this.cookieDel = cookieDel;
}
}
@RequestMapping("/main")
public String mallMain(Mall mall, HttpServletResponse response){
Cookie genderCookie = new Cookie("gender", mall.getGender());
if(mall.isCookieDel()) {
genderCookie.setMaxAge(0);
mall.setGender(null);
} else {
genderCookie.setMaxAge(60*60*24*30);
}
response.addCookie(genderCookie);
return "/mall/main";
}
웹페이지의 메인 페이지를 열람하는 요청인 /main URL이 요청되면 mallMain 메서드가 실행되면서 쿠키를 생성한 후 웹 사용자에게 쿠키를 전달한다.
쿠키는 Cookie 객체를 통해 간단히 만들 수 있다. Mall 객체는 사용자 측에서 오는 커맨드 객체이며 이 안에는 cookieDel 이라는 변수가 있다. cookieDel은 쿠키를 삭제할지 말지 결정하는 사용자에서 보내오는 데이터이며 이 cookieDel이 True일 경우 쿠키를 삭제하는 로직이 실행된다.
이 로직은 setMaxAge(0)로 만들어서 쿠키가 바로 삭제되도록 구현할 수 있다. setMaxAge는 쿠키가 사용자 PC에 초단위로 얼마만큼 남아있을지 결정하는 메서드다.
만일 사용자가 쿠키를 삭제하지 않을 것이라는 cookieDel이 False인 경우에는 쿠키의 기한을 60*60*24*30 초 즉 30일동안 늘린다.
그 후, 사용자에게 보낼 쿠키 데이터에 HttpServletResponse 객체의 addCookie 메서드를 통해 genderCookie 데이터를 넣어 나중에 쿠키 데이터를 서버가 이용하게 만든다.
사용자 PC에 쿠키 데이터가 보내지는 지 아닌지를 체크하는 기능과 만일 쿠키 데이터가 있을 경우 그 값을 얻을 수 있는 방법은 다음과 같다.
@RequestMapping("/index")
public String mallIndex(Mall mall,
@CookieValue(value="gender", required=false) Cookie genderCookie,
HttpServletRequest request) {
if(genderCookie != null)
mall.setGender(genderCookie.getValue());
return "/mall/index";
}
@CookieValue 어노테이션을 이용하면 HttpServletRequest을 통해 쿠키값을 읽을 필요없이 스프링 컨트롤러에서 파라미터로 바로 전달받을 수 있다. 여기서 주의할 것은 만일 required=false를 입력하지 않으면 쿠키가 없을 시 java.lang.IllegalStateException을 발생시키므로 주의해야한다. 따라서 defaultValue나 required=false를 사용하는 것이 좋다.