백엔드/JSP

JSP Servlet 기초 (8) : Session

두개의 문 2023. 6. 13. 22:44
세션 (Session)

 
▷ 세션 
- 쿠키와는 다르게 서버에서 생성되는 기본 객체
- 웹 서버에서 요청을 보낸 웹 브라우저(클라이언트)를 구분(식별)하기 위해 사용
- 웹 브라우저마다 하나씩 생성되어 웹 컨테이너에 저장
   → 이를 활용해 로그인 시 로그인과 관련된 중요한 정보, 웹 브라우저에 저장하면 민감한 정보 등을 세션에 대신 저장 
        ∴ 안정적, 보안 상의 문제점 해결
 


▷ 동작 메커니즘
❶ 웹 브라우저에서 서버로 요청 
❷ 서버에서 해당 브라우저를 식별할 수 있는 session 기본 객체를 생성
❸ 생성된 session을 JSESSIONID = 세션ID 형태로 쿠키를 생성하여 응답 
     ( ID는 session 객체 생성 시에 웹 컨테이너에 의해 자동으로 할당됨 )
    → 쿠키에 세션값을 담아 response로 웹 브라우저로 보냄 
❹ 브라우저는 세션ID 값을 가지는 쿠키를 로컬에 저장
❺ 이후 브라우저에서 서버로 자원을 요청할 때마다 세션 쿠키도 함께 전송 
    → 서버에서는 요청 시 쿠키 정보 확인 즉, JSESSIONID 쿠키의 값을 이용해 브라우저를 식별함
         만약 요청이 왔을 때 식별하지 못하는 세션 ID일 경우, 새로운 세션을 생성하게 됨
         ※ 브라우저에서 종료하거나 서버에서 session.validate( ) 메서드 호출 시, 세션 제거됨
 


▷ 주요 메서드

메서드 이름 반환 타입 설명
getAttribute( String name ) java.lang.Object 세션 속성명이 name인 속성의 값을 Object 타입으로 리턴함
해당되는 속성명이 없을 경우에는 null 값 리턴함
※ 이 메서드는 리턴타입이 Object 타입이므로 사용 시 실제 할당된 객체 타입으로 형변환(casting)을 해야 함
getAttributeNames( ) java.util.Enumeration 세션 속성의 이름들을 Enumeration 객체 타입으로 리턴함
getCreationTime( ) long 1970년 1월 1일 00시 00분 00초부터(epoch라고 부름) 해당 세션이 생성된 순간까지의 경과 시간을 밀리초로 계산하여 long형으로 리턴함
getId( ) java.lang.String 세션에 할당된 고유 식별자를 String 타입으로 리턴함
getMaxInactiveInterval( ) int 현재 생성된 세션을 유지하기 위해 설정된 세션 유효시간을 int형으로 리턴함 ( 가장 최근 요청 시점을 기준으로 계산 )
invalidate( ) void 현재 생성된 세션을 무효화시킴( = 제거 )
removeAttribute( String name) void 세션 속성명이 name인 속성을 제거
setAttribute( String name, Object value ) void 세션 속성명이 name인 속성에 속성값으로 value를 할당함
setMaxInactiveInterval( int interval ) void 세션을 유지하기 위한 세션 유지시간을 초 단위로 설정함
즉, 클라이언트가 설정한 시간동안 요청을 하지 않으면 세션을 소멸
isNew( ) boolean 세션객체가 새로 생성된 객체인지 기존의 세션 객체인지 판단함

 
 

< 요약 > 
  - 웹 서버에서 요청을 보낸 웹 브라우저(클라이언트)를 식별하기 위해 사용
  - JSP에서는 최초 요청 시 내장객체(기본 객체)로 세션이 생성됨 
    ( 이 때, Session ID도 생성 )
  - 생성된 세션에 setAttribute( ) 메서드, getAttribute( ) 메서드를 이용하여 값을 저장하고 사용
  - 세션 객체는 웹 서버에 생성된 객체이므로 중요한 정보를 저장하기 용이
  - 웹 브라우저(클라이언트)에서 종료하거나 서버에서 session.invalidate( ) 메서드 호출 시, 세션 객체 제거

 
 
▷ sessionSet.jsp 

 : session의 name 속성에 value 값을 할당해 세션을 생성해보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<% 
	// session에 데이터 저장 (session : 서버 쪽 쿠키)
	// 총 7개의 세션 생성해보자
	session.setAttribute("userId1", "test1234");
	session.setAttribute("userId2", "test5678");
	// * 배열 이용 
	String[] userIdName = { "userId3", "userId4", "userId5" };
	String[] userIdValue = { "test9012", "test3456", "test7890" };
	for (int i = 0; i < userIdName.length; i++){
		session.setAttribute(userIdName[i], userIdValue[i]);
	}
	// * SessionValue 값으로 정수와 실수 설정
 	session.setAttribute("userId6", 100_000_000L);
	session.setAttribute("userId7", 50000.50);
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<a href="sessionGet.jsp">session Get</a>
</body>
</html>

 

 

▶ 서버에 sessionSet.jsp를 요청해보자

 

 

▷ sessionGet.jsp

1. getAttribute(String name) 메서드를 이용해 session에서 데이터 얻기

   ※ 이 메서드는 리턴타입이 Object 타입이므로 사용 시 실제 할당된 객체 타입으로 형변환(casting)을 해야 함

   ① Object 타입으로 형변환

   ② 다시 String형으로 형변환시킨 후, 변수에 저장

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Enumeration" %>    
<% 
	// session에서 데이터 얻기
	// 1. getAttribute(String name) 메서드 이용 
	// ① Object 타입으로 형변환 
	//   getAttribute(String name)의 리턴타입 : Object 객체 
	Object obj1 = session.getAttribute("userId1");
	// ② 다운캐스팅 : 강제 형변환 
	String user1 = (String)obj1;
	out.println("userId1 : " + user1 + "<br />");
	
	Object obj2 = session.getAttribute("userId2");
	String user2 = (String)obj2;
	out.println("userId2 : " + user2 + "<br />");
	
	Object obj3 = session.getAttribute("userId3");
	String user3 = (String)obj3;
	out.println("userId3 : " + user3 + "<br />");
	
	Object obj4 = session.getAttribute("userId4");
	String user4 = (String)obj4;
	out.println("userId4 : " + user4 + "<br />");
	
	Object obj5 = session.getAttribute("userId5");
	String user5 = (String)obj5;
	out.println("userId5 : " + user5 + "<br />");
	
	Object obj6 = session.getAttribute("userId6");
	Long user6 = (Long)obj6;
	out.println("userId6 : " + user6 + "<br />");
	
	Object obj7 = session.getAttribute("userId7");
	Double user7 = (Double)obj7;
	out.println("userId7 : " + user7 + "<br />");
	
	out.println("-----------------------------<br/>");

 

 

2. Enumeration(열거형 인터페이스)를 이용하여 session의 모든 요소를 반복문으로 접근하기

   ① session의 key 이름과 value 값을 저장할 변수 선언

   ② getAttributeNames( ) 메서드를 이용해 session의 key 이름 얻어 Enumeration에 저장

        → 직렬화로 저장

   ③ Enumeration의 주요 메서드를 이용해 반복문을 통해 세션의 이름을 출력하자

Enumeration 인터페이스
- Collection 프레임워크가 만들어지기 전, Iterator의 이전 버전
- 컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스
- 메서드 정리
➊ boolean hasMoreElement( ) : 생성된 Enumeration의 요소가 있으면 true, 없으면 false 반환
❷ Object nextElement( ) : Enumeration 내의 다음 요소를 반환 
	// 2. Enumeration (열거형 클래스) 이용하여 
	//    session의 모든 요소를 반복문으로 접근하기
	// ① 변수 선언 
	String sName; 	// 세션요소의 key 이름
	String sValue; 	// 세션요소의 key 이름에 대한 값 
	// ② 세션 모든 요소의 key 이름 얻어오기
	//   getAttributeNames() 메서드의 리턴타입 : Enumeration 객체 
	Enumeration enums1 = session.getAttributeNames();
	
	while(enums1.hasMoreElements()){
		
        	sName = enums1.nextElement().toString();
        	// nextElement() 메서드의 반환타입 : Object
        	// -> Object의 toString()메서드 이용해서 문자열로 반환
		sValue = session.getAttribute(sName).toString();
		
		out.println("sName : " + sName + "<br / >");
		out.println("sValue : " + sValue + "<br />");
	}
	
	out.println("-----------------------------<br/>");

 

 

3. 세션 정보 얻기

① getId( ) 메서드를 통해 session의 유니크한 ID값을 얻어와 출력

② getMaxInactiveInterval( ) 메서드를 이용해 유효시간을 가져와 출력

     유효기간을 따로 설정하지 않았다면, 서버에 기본적으로 저장된 1800(30분)으로 출력됨

	//    ID : session 객체 생성 시에 웹 컨테이너에 의해 자동으로 할당됨 
	String sessionID = session.getId();
	out.println("SessionID : " + sessionID + "<br />");
	//    세션 만료시간 ( 단위 : 초 )
	int sessionInterval = session.getMaxInactiveInterval();
	out.println("세션 만료시간 : " + sessionInterval + "<br / >");
	
	out.println("-----------------------------<br/>");

 

 

4.  세션의 요소 삭제하기

    ① userId1, userId2를 삭제해보자
    ② 삭제된 세션 요소 확인 : 2번과 동일하게 Enumeration 객체 이용

	// ① userId1, userId2를 삭제해보자
	session.removeAttribute("userId1");
	session.removeAttribute("userId2");
	// ② 삭제된 세션 요소 확인 : 2번과 동일하게 Enumeration 객체 이용
	Enumeration enums2 = session.getAttributeNames();
	while(enums2.hasMoreElements()){
		sName = enums2.nextElement().toString();
		sValue = session.getAttribute("sName").toString();
		out.println("sName : " + sName + "<br />");
		out.println("sValue : " + sValue + "<br / >");
	}
    out.println("-----------------------------<br/>");

 

 

5. 세션 무효화시키기 ( = 로그아웃 )

① 지금까지의 세션 작업 내용을 초기화

② 실제로 초기화되었는지 확인하기 

	// ① 지금까지의 세션 작업 내용을 초기화 
	session.invalidate();  // ⇒ 디버그 중단점
	// ② 확인 
	if(request.isRequestedSessionIdValid()){
		out.println("현재 세션이 살아있습니다.");
	} else {
		// 세션이 무효화된 상태 → 로그아웃된 상태로 다시 로그인해야 함 
		out.println("현재 세션이 초기화되었습니다.");
	}
		
%>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

 

 

▷ sessionTest.jsp

: 실제로 세션이 삭제가 되었는지 확인해보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>    
      
<% 
	Enumeration enums = session.getAttributeNames(); // ⇒ 디버그 중단점
	int i = 0;
	while(enums.hasMoreElements()){
		i++;
		String sName = enums.nextElement().toString();
		String sValue = session.getAttribute("sName").toString();
		
		out.println("sName : " + sName + "<br />");
		out.println("sValue : " + sValue + "<br />");
	}
	
	if(i==0){
		out.println("해당 세션이 삭제되었습니다.");
	}
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>