본문 바로가기

학원/복기

[Servlet] 세션(Session)

세션(Session)

 

세션(Session)은 서버(웹프로그램)와 클라이언트(브라우저)의 연결 지속성을 제공하기 위한 정보를 서버에 저장하는 값(객체)을 뜻하며,  WAS 프로그램에 의해 관리된다.

 

일반적으로 세션은 보안관련 정보(권한에 관한 정보)를 저장할 목적으로 사용한다.

세션에 객체가 저장되어 있으면 권한이 있는 사용자, 저장되어 있지 않으면 권한이 없는 사용자이다. 세션을 이용해 권한이 있는 사용자와 권한이 없는 사용자에게 다른 결과를 응답해줄 수 있도록 한다.

 

세션을 구분하기 위한 식별자(SessionId)를 이용하여 클라이언트를 구분해 세션에 값(객체)를 저장하여 사용한다.

이를 위해선 세션 바인딩이라는 작업이 필요하다.


세션 바인딩(Session Binding)은 연결 지속성을 제공하기 위한 값(객체)이 저장된 세션을 웹프로그램에서 사용할 수 있도록 결합하는 작업이다. 세션 바인딩은 세션에 데이터를 저장하거나 세션에서 데이터를 가져오는 과정을 뜻하며 WAS 프로그램이 작업해준다. 

 

클라이언트에게 [JSESSIONID] 이름의 쿠키값을 제공받지 못한 경우에는 메모리에 새로운 세션을 생성하여 바인딩 처리하고 생성된 세션의 식별자(SessionId)를 클라이언트에게 [JSESSIONID] 이름의 쿠키값으로 전달한다. 

→ 클라이언트에 저장된  [JSESSIONID] 이름의 쿠키값은 브라우저 종료시 소멸된다.

 

클라이언트에게 [JSESSIONID] 이름의 쿠키값을 제공받은 경우에는 세션 트랙킹하여 바인딩 처리한다. 

→ 세션 트랙킹이 실패한 경우 새로운 세션을 생성하고 세션의 색별자(SessionId)를 클라이언트에게 전달한다. 


세션 트랙킹 (Session Tracking)은 클라이언트에게 제공받은  [JSESSIONID] 이름의 쿠키값과 메모리에 저장된 세션의 식별자(SessionId)를 비교해서 검색하는 작업이다. 세션 트래킹을 통해 사용자의 상태를 지속적으로 추적하고 유지할 수 있다.

 

 

즉, 세션 바인딩은 세션 객체와 데이터를 연결하는 과정이며, 세션 트래킹은 사용자의 세션을 식별하고 추적하는 메커니즘이다. 세션 바인딩은 데이터를 세션에 저장하고 사용하는 것이고, 세션 트래킹은 세션을 식별하고 해당 세션과 연결된 데이터를 가져오는 것이다. 

 


예제)

 

세션을 바인딩하여 클라이언트에게 바인딩된 세션정보를 전달하여 응답하는 서블릿 생성

 

@WebServlet("/session.itwill")
public class SessionServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//파일형태(MimeType)를 변경
		response.setContentType("text/html;charset=utf-8");
		//응답파일을 생성하기 위한 출력스트림을 반환받아 저장
		PrintWriter out=response.getWriter();
        
        	//코드작성
            	//코드작성
           	// ...
	}
}

1. 바인딩 처리된 세션(Session 객체)을 반환 

 

HttpServletRequest.getSession() : 바인딩 처리된 세션(Session 객체)을 반환하는 메소드 

→ 새로운 세션을 생성하여 바인딩하거나 기존 세션을 트렉킹하여 바인딩 처리한다.

 

HttpSession 객체 : 연결 지속성을 제공하는 값(객체)을 저장하기 위한 객체 

HttpSession session=request.getSession();

 

 

2. HTML 문서 만들어 응답 

 

HttpSession.isNew() : 세션을 트렉킹하여 바인딩된 경우 [false]를 반환하고 세션을 생성하여 바인딩된 경우 [true]를 반환하는 메소드 

HttpSession.getId() : 세션을 구분하기 위한 식별자(SessionId)를 반환하는 메소드

HttpSession.getMaxInactiveInterval() : 세션 유지시간을 반환하는 메소드 

→ 세션 유지시간(초) :세션을 사용하지 않을 경우 서버 메모리에서 세션이 자동 소멸되도록 설정하는 시간 

→ 세션의 기본 유지시간은 30분으로 설정되어있다. 

if(session.isNew()) {
	out.println("<p>세션을 생성하여 바인딩 하였습니다.</p>");
} else { 
	out.println("<p>세션을 트렉킹하여 바인딩 하였습니다.</p>");
}
out.println("<p>세션 고유값(SessionId) = " +session.getId()+"</p>");
out.println("<p>세션 유지시간 = " +session.getMaxInactiveInterval()+"</p>");

 

HttpSession.setAttribute(String attributeName, Object attributeValue

→ HttpSessinon 객체에 연결 지속성을 제공하기 위한 값(객체)를 저장하는 메소드 

→ 매개변수에 속성값을 구분하기 위한 속성명과 연결 지속성을 제공하기 위한 값을 전달한다.

→ 매개변수로 전달받은 속성명과 같은 이름의 속성값이 존재할 경우 덮어씌우기한다. - 속성값 변경

동일한 세션을 바인딩한 모든 웹프로그램에게 속성명으로 속성값을 제공받아 사용할 수 있다. 즉, 하나의 클라이언트는 세션을 사용하여 모든 웹프로그램에게 객체를 공유하여 제공할 수 있다. 

session.setAttribute("now", new Date());//세션에 now라는 이름으로 Date객체 저장

 

HttpSession.getAttribute(String attributeName) : HttpSession 객체에 저장된 속성값을 반환하는 메소드 - 매개변수에 속성값을 구분하기 위한 속성명을 전달한다.

일반적으로 세션에서 가져온 속성 값은 Object 타입으로 반환된다. 따라서 해당 속성 값을 사용하기 위해서는 적절한 타입으로 형변환을 해주어야 한다. 따라서 반드시 명시적 객체 형변환을 이용해야 한다.

→ 매개변수로 전달받은 속성명의 속성값이 없는 경우 [null]을 반환한다.

Date now=(Date)session.getAttribute("now");
out.println("<p>세션 유지시간 = "+now+"</p>");

 

HttpSession.removeAttribute(String attributeName) : HttpSessinon 객체에 저장된 속성값을 삭제하는 메소드 - 매개변수에 속성값을 구분하기 위한 속성명을 전달한다. 

session.removeAttribute("now");

 

HttpSession.invalidate() : 바인딩된 세션을 언바인딩해서 무효화 처리하는 메소드 - 바인딩된 HttpSession 객체를 제거한다.

session.invalidate();

 

invalidate() 메소드를 사용하는 이유는 다음과 같다.

  1. 로그아웃: 일반적으로 사용자가 로그아웃을 요청하면 세션을 무효화하여 사용자의 인증 정보와 세션 데이터를 모두 삭제한다. 이렇게 함으로써 사용자는 더 이상 해당 세션으로 인증을 받을 수 없게 되며, 새로운 세션을 생성하여 로그인해야 한다.
  2. 보안 강화: 세션은 보안과 관련된 중요한 정보를 저장할 수 있다. 세션을 무효화함으로써 이전 세션에 저장된 정보가 남아있지 않도록 하여 보안을 강화할 수 있다. 특히, 사용자가 로그아웃하거나 일정 시간이 지나면 세션을 무효화하여 해당 세션을 악의적으로 이용하는 시도를 방지할 수 있다. 
  3. 리소스 해제: 세션에는 서버 측에서 사용하는 리소스(메모리, 연결 등)가 할당될 수 있다. 세션을 무효화하여 이러한 리소스를 해제하고, 서버 자원을 효율적으로 관리할 수 있다. 

 

[전체 소스코드]

 

package xyz.itwill.servlet;

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.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

//세션을 바인딩하여 클라이언트에게 바인딩된 세션정보를 전달하여 응답하는 서블릿
@WebServlet("/session.itwill")
public class SessionServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		
		HttpSession session=request.getSession();
		
		//HTML 문서 만들어 응답
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		out.println("<head>");
		out.println("<meta charset='UTF-8'>");
		out.println("<title>Servlet</title>");
		out.println("</head>");
		out.println("<body>");
		out.println("<h1>세션(Session)</h1>");
		out.println("<hr>");
		if(session.isNew()) {
			out.println("<p>세션을 생성하여 바인딩 하였습니다.</p>");
		} else { 
			out.println("<p>세션을 트렉킹하여 바인딩 하였습니다.</p>");
		}
		out.println("<p>세션 고유값(SessionId) = " +session.getId()+"</p>");
		out.println("<p>세션 유지시간 = " +session.getMaxInactiveInterval()+"</p>");
		
		session.setAttribute("now", new Date());//세션에 now라는 이름으로 Date객체 저장 
		
		Date now=(Date)session.getAttribute("now");
		out.println("<p>세션 유지시간 = "+now+"</p>");
		
		session.removeAttribute("now");
		
		session.invalidate();
		
		out.println("</body>");
		out.println("</html>");
	}
}