<< 학습 목표 >>

1. 세션이 생성되는 시점을 설명할 수 있다.

2. 세션에 데이터를 저장할 수 있다.

3. 세션에 저장된 데이터를 꺼낼 수 있다.

4. 세션에 저장된 데이터를 삭제할 수 있다.

5. 세션을 삭제할 수 있다.


전 글에서는 쿠키를 사용해 상태 정보를 저장하고 꺼냈음

이번에는 세션(Session)을 사용해 상태 정보를 저장하고 꺼내는 방법을 알아보자

 

세션을 사용하는 이유는 쿠키를 사용하는 이유와 같음

세션도 쿠키처럼 상태 정보를 저장할 수 있음

쿠키와 세션이 다른점은 세션은 서버에 저장되는 공간임

그렇다면 전 글에서 배웠던 쿠키는?

더보기

쿠키는 클라이언트의 PC에 저장됨


 

쿠키는 클라이언트의 PC에 저장되므로 쿠키가 저장되있는 위치를 확인할 수 있지만 세션은 서버에 저장되므로 따로 확인할 방법이 없음

 

쿠키를 어느 음식점의 쿠폰 서비스를 예로 들었음

점원 = 웹 서비스

쿠폰 = 상태 정보

이고 쿠폰을 고객이 가져가는 방식이 쿠키라고 했음

 

세션도 마찬가지로

점원 = 웹 서비스

쿠폰 = 상태 정보

이나 쿠폰을 고객이 가져가는 방식이 아닌 매장에서 보관하는 방식임

 

세션 방식을 비유하자면

점원이 쿠폰에 도장을 찍고 "쿠폰은 저희가 보관하고 있을께요. 다음에 오실 때 이름을 말씀해주시면 고객님의 쿠폰에 도장 찍어드리겠습니다." 임


웹 서비스(서블릿)에서 세션을 만들고 세션에 정보를 저장하고 세션에 저장된 데이터를 꺼내는 방법을 배워보자

 

<< 서블릿에서 세션을 만드는 방법 >>

 

세션을 만들 때는 요청 정보(HttpServletRequest)가 가지고 있는 getSession 메서드를 호출해야함

쿠키와 만드는 방법이 완전히 다르니 주의하자

 

chapter05 -> CreateSession 서블릿을 추가하고 아래 코드를 추가하자

package chapter05;

import java.io.IOException;
import java.time.LocalDateTime;

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("/chapter05/session/create")
public class CreateSession extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		
		LocalDateTime now = LocalDateTime.now();
		
		session.setAttribute("now", now);
	}

}

 

코드를 보자

클라이언트가 웹 서비스에 처음 접근했다면 세션은 없는 상태임

세션이 없는 상태에서 getSession 메서드가 동작(1)하면 세션을 만든 후 세션을 반환함

 

세션은 따로 저장하지 않음

세션은 서버에 저장해두는 클라이언트의 상태 정보이므로 따로 저장하지 않아도 알아서 서버에 저장됨

 

처음 접근했을 때 세션을 만들었으므로 클라이언트가 두 번째, 세 번째, ..., n 번째 접근하는 경우에는 getSession 메서드가 만들었던 세션을 반환함

 

잠시 이 서블릿에 접근하기 전 아래 코드를 좀 더 추가하자

 

쿠키의 경우 필요할 때 만드는 방식이 명확하지만 세션의 경우 해당 서블릿에 최초로 접근했을 경우에만 getSession 메서드를 통해서 세션을 만들고 최초 이후 n번째 접근일 때는 getSession 메서드가 만들어진 세션을 반환하므로 방금 만들어진 세션인지 아닌지(1), 세션이 최초로 만들어진 날짜는 언제인지(2), 세션에 마지막으로 접근한 날짜는 언제인지(3) 를 출력해보는 것

(1) isNew메서드 : 클라이언트가 최초로 접근해 getSession메서드가 방금 세션을 만들었다면 true를 반환, 클라이언트가 n번째 접근해 getSession메서드가 만들어진 세션을 반환했다면 false를 반환

(2) getCreationTime메서드 : getSession메서드가 세션을 만든 날짜를 반환

(3) getLastAccessedTime메서드 : 마지막으로 getSession메서드로 세션을 꺼낸 날짜를 반환 

 

이제 서버를 시작하고 해당 서블릿에 접근해보자

해당 서블릿에 처음 접근했으므로 다음과 같이 isNew 메서드가 true를 반환함(1)

 

같은 경로로 두 세번 더 접근해보면 그 다음부터는 isNew 메서드가 false를 반환함

두 번째부터는 만들어진 세션을 사용하므로 isNew 메서드가 false를 반환하는 것(2), (3)

세션이 만들어진 날짜와 세션을 마지막으로 접근한 날짜값을 보면 우리가 알고 있는 연, 월, 일, 시, 분, 초 형식이 아니라 조 단위의 엄청 큰 숫자가 출력되고 있음

이는 당연히도 getCreationTime 메서드와 getLastAccessedTime 메서드가 반환하는 값인데 이 값은 현재 날짜를 유닉스 타임스탬프(UNIX TIMESTAMP) 라는 것으로 표현한 것

 

유닉스 타임스탬프가 뭘까?

더보기

자세한 얘기를 하면 다른쪽으로 길게 얘기를 해야하니 여기서는 간단하게만 언급하겠음

만약 유닉스 타임스탬프에 대해서 정확하고 자세하게 이해하고 싶다면 별도로 찾아보자

현재 날짜 라는 기준은 나라나 지역마다 다름

대한민국에 살고 있는 여러분의 현재 시간과 미국에 살고 있는 누군가의 현재 시간은 다를 것

현재라는 시점은 똑같지만 시간은 다름

그러나 유닉스 타임스탬프를 사용하면 대한민국에 살고 있는 여러분의 시간과 미국에 살고 있는 누군가의 현재 시간은 같음

( 다시 한번 언급하지만 정확하고 자세하게 이해하고 싶다면 별도로 찾아보자 )

서블릿을 사용해 서비스를 개발하는 사람은 한국 사람뿐만 아니라 전세계 어느 나라 사람이나 될 수 있으므로 서블릿에서는 이렇게 날짜 정보를 유닉스 타임스탬프 형식으로 반환해주기도 함


 

세션이 만들어진 날짜나 세션을 마지막으로 접근한 날짜를 알고 싶다면 다음과 같이 Instant와 ZoneId, LocalDateTime을 사용하면 됨

(Instant, ZoneId, LocalDateTime은 자바의 java.time 패키지에 속한 클래스들이므로 이들에 대해서 알고 싶다면 자바의 날짜와 관련된 파트를 공부하자)

 

여기까지 << 서블릿에서 세션을 만드는 방법 >> 을 배웠음


<< 세션에 데이터를 저장하는 방법 >>

 

세션에 데이터를 저장할 때는 setAttribute 메서드를 사용함

우리는 이미 setAttribute 메서드를 사용해서 데이터를 저장(1)했음

 

세션에 데이터를 저장하는 방법을 좀 더 깊게 들어가보자

chatper05 -> SaveSession 서블릿을 만들고 아래 코드를 입력하자

package chapter05;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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("/chapter05/session/save")
public class SaveSession extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		
		session.setAttribute("data1", 1);
		session.setAttribute("data2", 171.1);
		session.setAttribute("data3", "문자열");
		
		int[] array = {1, 2, 3};
		session.setAttribute("data4", array);
		
		List<Integer> list = new ArrayList<>();
		list.add(3);
		list.add(2);
		list.add(1);
		session.setAttribute("data5", list);
	}

}

 

앞서 배웠듯 쿠키에는 문자열만 저장할 수 있지만 세션에는 내가 저장하고 싶은 어떤 데이터든 저장할 수 있음

 

정수와 실수 같은 기본 데이터 타입인 데이터들을 저장할 수 있음(1), (2)

또 문자열, 배열, 리스트 같은 참조 데이터 타입인 데이터들을 저장할 수 있음(3), (4), (5)

이외에도 내가 만든 클래스를 사용해 객체를 생성하고 그 객체를 세션에 저장할 수도 있음

 

특히나 데이터만 저장하면 안되고 저장할 데이터에 이름을 붙여줘야함

setAttribute 메서드의 첫 번째 인자가 저장할 데이터의 이름이고 두 번째인자가 저장할 데이터임

 

서버를 재시작 한 후 해당 서블릿에 접근해보자

그랬을 때 웹 페이지나 콘솔에는 아무것도 출력되지 않음

왜? 우리는"세션에 데이터를 저장해" 라고 명령을 내렸지 "웹페이지에 무언가를 출력해" 또는 "콘솔에 무언가를 출력해" 를 내리지 않았으므로...

 

여기까지 << 세션에 데이터를 저장하는 방법 >> 을 배웠음


<< 세션에 저장한 데이터를 꺼내는 방법 >>

 

세션에 저장한 데이터를 꺼낼 때는 getAttribute 메서드를 사용함

getAttribute메서드는 데이터를 저장할 때 사용했던 이름을 통해 데이터를 꺼낼 수 있음

 

chapter05 -> GetSession 서블릿을 만들고 아래 코드를 추가하자

package chapter05;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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("/chapter05/session/save")
public class SaveSession extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		
		session.setAttribute("data1", 1);
		session.setAttribute("data2", 171.1);
		session.setAttribute("data3", "문자열");
		
		int[] array = {1, 2, 3};
		session.setAttribute("data4", array);
		
		List<Integer> list = new ArrayList<>();
		list.add(3);
		list.add(2);
		list.add(1);
		session.setAttribute("data5", list);
	}

}

 

getAttribute메서드로 데이터를 꺼낼 때 주의해야할 점은 저장한 데이터의 타입에 맞게 형변환 해줘야한다는 점임

 

세션은 "setAttribute메서드를 사용해서 세션에 어떤 데이터도 저장할 수 있다" 라는 특징이 있지만 어떤 데이터가 저장되어있는지 세션은 알지 못함

그저 개발자가 "이거 저장해줘, 저거 저장해줘" 라고 했으니 저장만 하고 있을 뿐 "이거는 정수구나, 저거는 문자열이구나" 인지하면서 저장하지 않음

 

따라서 getAttribute메서드로 데이터를 꺼내면서 우리가 저장했던 데이터의 타입에 맞게 형변환을 반드시 해줘야함

 

이제 서버를 재시작 하고 해당 서블릿에 접근해보자

그럼 세션에 저장해둔 값이 콘솔에 출력됨

 

세션에 저장한 데이터 꺼내기의 마지막으로 getAttribute메서드로 데이터를 꺼낼 때는 이름을 정확하게 입력해야함

이름을 잘못 입력하면 getAttribute 메서드는 null 상태를 반환함

아래와 같이 꺼낼 데이터의 이름을 잘못 입력한 상태에서 해당 서블릿에 접근하면 NullPointerException이 발생함

( 아래 코드는 입력하지 말고 참고만 하자 )

 

여기까지 << 세션에 저장한 데이터를 꺼내는 방법 >> 를 배웠음


<< 세션에 저장한 데이터를 지우는 방법 >>

 

전 글에서 배웠듯 쿠키에는 데이터 조각 조각을 저장해두니 조각의 수만큼 쿠키가 생성될꺼고 쿠키에 저장한 데이터를 지우는 방법은 쿠키 자체를 삭제하는 방법 밖에 없었음

그러나 세션에는 이것 저것 저장해둘 수 있으므로 세션 자체를 삭제하면 그 안에 저장해둔 모든 데이터가 삭제됨

 

이번에는 세션에 저장한 특정 데이터만 지워보자

 

세션에 저장한 특정 데이터를 지울 때는 removeAttribute 메서드를 사용함

removeAttribute 메서드의 인자로 지울 데이터의 이름을 지정하면 해당 데이터만 지워짐

chapter05 -> RemoveSession 서블릿을 만들고 아래 코드를 추가하자

package chapter05;

import java.io.IOException;
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("/chapter05/session/remove")
public class RemoveSession extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		
		session.removeAttribute("data1");
	}

}

 

서버를 재시작하고 해당 서블릿에 접근하면 이름이 data1인 데이터가 세션에서 지워졌음

그 후 이름이 GetSession인 서블릿에 접근해보면 NullPointerException이 발생함

왜? 방금 세션에서 이름이 data1인 데이터를 지웠으므로...

 

여기까지 << 세션에 저장한 데이터를 지우는 방법 >> 을 배웠음


<< 세션을 지우는 방법 >>

 

종종 세션 자체를 지워야하는 경우가 생김

그럴 때는 invalidate메서드를 사용함

 

chapter05 -> InvalidateSession 서블릿을 만들고 아래 코드를 추가하자

package chapter05;

import java.io.IOException;
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("/chapter05/session/invalidate")
public class InvalidateSession extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		
		session.invalidate();
	}

}

 

서버를 재시작하고 해당 서블릿에 접근하면 세션 자체가 삭제됨

그 후 이름이 GetSession 서블릿으로 접근하면 역시나 NullPointerException이 발생함

 

여기까지 << 세션을 지우는 방법 >> 을 배웠음


여기까지 세션과 관련된 것들을 전부 배웠음

 

쿠키는 클라이언트에 저장되므로 클라이언트가 쿠키를 볼 수 있음

그래서 쿠키 안에 중요한 개인정보나 민감한 정보를 저장할 수 없음

 

세션은 서버에 저장되므로 클라이언트가 세션을 볼 수 없음

그래서 세션 안에 중요한 개인정보나 민감한 정보를 저장해도 됨

 

쿠키, 세션을 어떻게 활용할 지는 다음 글인 프로젝트에서 배우도록 하자

728x90
LIST