세션(session) & 쿠키(cookie)

기록하는 용도·2022년 9월 27일
0

HTTP 프로토콜

Stateless 특징

  • 요청과 응답이 끝나면 연결을 종료

http 프로토콜은 상태를 유지하지않는 즉, 사용자 정보를 유지하지않는다는 특성을 갖고있는 stateless 특징을 갖고있다.

세션 관리

사용자 정보를 일정 조건동안 유지

사용자 정보를 유지하는 방식

(상태 정보를 유지하는 방식)

클라이언트 측에 저장하는 작은 정보
저장 용량에 제한(4kb)
저장 데이터 타입의 제한, 문자열만 가능
Cookie 생성시 유효시간을 설정하지않으면 브라우저 실행시에만 유효, 
유효시간 설정하면 그 유효시간까지 해당 Cookie는 지속되어 사용할 수 있다.



2. Session

사용자 정보를 서버 측에 저장
저장 데이터의 타입 및 용량에 제한이 없음
(but 쿠키는 문자열 타입만 가능 4kb로 저장 용량이 제한)
로그인, 로그아웃시에 세션이 이용된다.
세션 유효 기간 
(WAS의 conf/web.xml에 session timeout이 설정 : apache tomcat 기본 설정은 30분)
1) 지정한 유효시간 내에 새로운 요청이 없으면 세션 만료
2) 브라우저 종료시 세션 만료
3) 로그아웃시 세션 만료


client1이 request를 보내고, response하는 과정이 있다.
기본적으로 연결이 끊어져야한다.
10억명이 있다고 하면 이 정보를 끊지않고 유지한다면 서버 메모리 증설 낭비이다.
이렇듯 정보를 유지하지않는게 효율적이었지만, 필요시 (인증기관으로 활동해야하는 카페, 블로그 활동 등) 일정 조건만은 사용자를 유지해야한다는 서버의 자원 활용에 더 효율적이라는 판단이 선다면 세션 & 쿠키를 사용하는 방법이 있다.

사용자 정보 유지, 상태 유지, stateful함을 위해 세션관리를 한다.
세션관리에는 세션, 쿠키가 있고 세션관리가 필요한 이유는 요청이 들어오면 응답이 끝나는 http의 기본 설계때문에 존재한다.


Cookie

  1. 서블릿이 쿠키 생성해서 클라이언트 측에 저장
    클라이언트가 서버에 접속할 때 서버 프로그램이 클라이언트 측으로 쿠키를 전송하고 클라이언트 측에 저장한다.
  2. 클라이언트가 접속하면 쿠키 존재여부를 확인하고 후속 작업 수행
    (이후 클라이언트가 서버에 재접속하면 서버 프로그램은 해당 쿠키의 정보를 확인해 후속 작업을 수행한다.)

SetCookieServlet

package step2;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/setCookie")
public class SetCookieServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html>");
		out.print("<body bgcolor=yellow>");
		out.print("<h3>" + this.getServletName() + "</h3>");
		
		String now = new Date().toString().replace(" ", "-");
		Cookie cookie = new Cookie("saveTime", now);
		
		cookie.setMaxAge(30);
		response.addCookie(cookie);
		
		out.print("쿠키를 생성해서 클라이언트에 전달! 저장된 쿠키 정보 : "+now+"<br><br>");
		out.print("<a href=getCookie>GetCookieServlet으로 이동</a>");
		out.print("</body>");
		out.print("</html>");
		out.close();
	}

}
Cookie cookie = new Cookie("saveTime", now);
		
cookie.setMaxAge(30);
response.addCookie(cookie);

쿠키를 현재 시간의 값을 value로 넣어 30초 동안 유효할 수 있도록 설정하고, 쿠키를 생성한다.

GetCookieServlet

package step3;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class GetCookieServlet
 */
@WebServlet("/getCookie")
public class GetCookieServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html>");
		out.print("<body bgcolor=lime>");
		out.print("<h3>" + this.getServletName() + "</h3>");
		
		Cookie[] cookies = request.getCookies();
		System.out.println("cookie array : " + cookies);
		
		if(cookies!=null) {
			String info = null;
			for (int i=0; i<cookies.length; i++) {
				if (cookies[i].getName().equals("saveTime")) {
					info = "SetCookieServlet이 저장한 saveTime Cookie의 value:" + cookies[i].getValue();
					break;
				}
			}
			if(info==null) {
				out.print("saveTime Cookie가 존재하지않습니다.");
			}else {
				out.print(info);
			}
		}else {
			out.print("쿠키가 존재하지않습니다");
		}
	}
}
Cookie[] cookies = request.getCookies();

클라이언트에 저장된 쿠키 중 saveTime name의 cookie를 확인해서 존재하면 쿠키의 value 정보를 화면에 출력하도록 한다.



Session

HttpSession 관련 주요 메소드

HttpServletRequest 의 method

  • request.getSesstion() or request.getSession(true);
    : 기존 세션이 없으면 새로 생성해서 반환, 있으면 기존 세션을 반환
    (로그인했으면 기존반환 없으면 생성해서 반환)
  • request.getSession(false) : 기존 세션이 없으면 null 반환, 있으면 기존 세션을 반환

HttpSession의 method

  • session.setAttribute(name,value) : 세션 객체에 name과 value 쌍으로 정보를 저장
  • session.getAttribute(name) : Object -> name을 이용해 세션에 저장된 정보를 반환
    memberVO타입으로 casting 해서 member.getname
  • session.invalidate() : 세션을 무효화시킴. 주로 로그아웃시 사용



Session 예제

package step4;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.MemberVO;

/**
 * Servlet implementation class SessionOneServlet
 */
@WebServlet("/one")
public class SessionOneServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html>");
		out.print("<body bgcolor=yellow>");
		out.print("<h3>" + this.getServletName() + "</h3>");
		
		HttpSession session = request.getSession();
		out.print("<h3>세션이 없으면 생성, 있으면 기존 세션을 사용 </h3>");
		out.print("현재 세션 아이디 " + session.getId());
		
		MemberVO memberVO = new MemberVO("java", "b", "김씨", "서울");
		session.setAttribute("member",memberVO);
		out.print("<br><br>" + memberVO.getName() + " 회원객체를 세션에 저장");
		out.print("<br><br><a href=two>SessionTwoServlet</a>");
		out.print("<br><br><a href=three>SessionThreeServlet</a>");
		out.print("</body>");
		out.print("</html>");
		out.close();
	}
}
HttpSession session = request.getSession();

세션을 생성 : getSession() -> 기존 세션이 없으면 새로 생성, 있으면 기존 세션을 반환
내부적으로 접속한 클라이언트에게 응답시 jsession 라는 name의 cookie를 전송해 저장하게 한다.



SessionTwoServlet

세션이 존재하는지 확인하고 세션이 존재하면 세션 내의 회원 정보를 반환받아 아이디와 이름을 출력하도록 한다.

package step5;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.MemberVO;

/**
 * Servlet implementation class SessionTwoServlet
 */
@WebServlet("/two")
public class SessionTwoServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html>");
		out.print("<body bgcolor=yellow>");
		out.print("<h3>" + this.getServletName() + "</h3>");

		HttpSession session = request.getSession(false);
		if (session != null) {
			MemberVO memberVO = (MemberVO) session.getAttribute("member");
			if (memberVO != null)
				out.print("아이디 : " + memberVO.getId() + " 이름 : " + memberVO.getName());
			else
				out.print("세션은 존재하나 회원 객체는 존재하지않습니다");
		} else {
			out.print("세션이 존재하지않습니다");
		}
		out.print("<br><br><a href=one>SessionOneServlet</a>");
		out.print("<br><br><a href=three>SessionThreeServlet</a>");
		out.print("</body>");
		out.print("</html>");
		out.close();
	}
}



SessionThreeServlet

package step6;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class SessionThreeServlet
 */
@WebServlet("/three")
public class SessionThreeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html>");
		out.print("<body bgcolor=orange>");
		out.print("<h3>" + this.getServletName() + "</h3>");
		
		HttpSession session = request.getSession(false);
		if(session!=null) {
			session.invalidate();
			out.print("session invalidate : 세션을 무효화시킴");
		}
		out.print("<br><br><a href=one>SessionOneServlet</a>");
		out.print("<br><br><a href=two>SessionTwoServlet</a>");
		out.print("</body>");
		out.print("</html>");
		out.close();
	}

}

0개의 댓글