이전글
세션(Session)이란?
세션은 HTTP 프로토콜을 이용하는 웹 환경에서 상태를 유지하기 위한 기술입니다. HTTP는 요청과 응답으로 이루어지며, 새로고침이나 특정 URL을 요청할때마다 새로운 HTTP 요청이 생성되기때문에 이들간에 상태를 유지할 수 있는 방법이 없습니다. 예를들어 /login.do 라는 URL에서 로그인을 했다고 하더라도 /boards 페이지로 이동하게 되면 새로운 HTTP 요청이므로 로그인을 했다는 정보를 어딘가에 확인할 수 없습니다. DB를 통해 로그인시에 login이라는 상태를 저장 후 logout시에 logout이라고 update 하는 방식으로 하면 되는거 아니야? 라고 생각 할 수도 있겠지만 대규모 어플리케이션일수록 DB는 부하를 가장 많이 받는 대상이며, 연산이 늘어날수록 병목이 되는 대상이 되기때문에 최대한 부담을 어플리케이션쪽으로 몰아주는것이 좋습니다.
따라서 HTTP의 무상태(Stateless)한 특성을 극복하고자 나온 기술이 쿠키와 세션입니다. 이 둘은 특정 데이터를 저장해두고 페이지를 이동하거나 새로고침 하는 등 HTTP 요청이 매번 발생해도 특정 상태(데이터)를 유지할 수 있는 기술입니다. 이 둘의 차이를 간략하게 설명하자면 쿠키는 브라우저(클라이언트측)에 저장된다는 점이며, 세션은 서버측에 생성되어 저장된다는 점 입니다. 그러나 세션을 식별하기 위한 세션ID값은 쿠키를 이용하여 보관합니다. 더욱 자세한 내용은 이전글을 참조합니다.
JSP에서 세션 생성하기
세션은 브라우저 단위로 생성되어집니다. 즉 하나의 컴퓨터에서 Explorer와 Chrome을 각각 실행하고 서버에 접속했다면 WAS에는 각각 두 개의 세션이 생성됩니다. JSP를 기준으로 세션은 page 디렉티브의 session 속성을 true로 지정해주면 해당 페이지를 요청시에 최초 한 번 세션이 생성되어지는데, 기본값이 true이기때문에 명시적으로 false로 지정해주지만 않는다면 세션이 생성됩니다. JSP 페이지에서는 request, application 등의 기본객체처럼 session 이라는 기본객체를 제공하여 세션객체를 조작할 수 있습니다.
/createSession.jsp
<%@ page contentType="text/html; charset=utf-8" session="true"%>
<html>
<head>
</head>
<body>
<h1>세션 생성 성공</h1>
<%= session %>
</body>
</html> |
cs |
최초 요청시 서버측에 생성되어 이후 브라우저가 종료 될때 사라집니다.
두번째 방법 HttpServletRequest 객체를 통해 생성하기
Servlet을 통해서 생성하거나 JSP의 request 기본객체를 통해 세션을 생성할 수 있습니다. HttpServletRequest 객체를 통해 생성하는 방법입니다. service() 메서드나 doGet(), doPost()등의 첫번째 매개변수로 넘어오는 HttpServletRequest 객체의 getSession()메서드를 사용합니다.
getSession() 메서드는 세션이 이미 존재하는 경우 해당 세션을 리턴하고, 세션이 존재하지 않으면 새로 생성하여 리턴합니다.
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
} |
cs |
만약 세션이 존재하지 않는 경우 생성하지 않고 null을 반환받고 싶은경우 getSession(boolean create) 를 사용합니다.
HttpSession session = request.getSession(false); |
cs |
세션이 생성되는 과정
세션은 브라우저 단위로 생성되어지고 최초 요청시 생성되어진다고 했습니다. 또한 서버측에 생성되어진 세션은 브라우저별로 생성된 세션을 구분할 수 있는 세션 ID를 갖게 되는데, 세션이 생성 되어질 때 세션ID를 브라우저측에 응답하고 브라우저는 이것을 쿠키로 저장합니다.
1. 브라우저가 서버측에 특정 페이지를 요청합니다. /createSession.jsp 요청
GET http://localhost/createSession.jsp HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: ko-KR
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: localhost
Connection: Keep-Alive
2. 서버에서는 현재 페이지의 page 디렉티브의 session 속성값이 true이면 세션을 생성하고 해당 세션을 구분할 수 있는 ID값을 HTTP 응답 메시지를 통해 리턴합니다. JSESSIONID라는 쿠키를 리턴했는데, 서버에서 세션을 생성하고 해당 세션을 구분하기 위한 세션 ID를 쿠키로 만들어 리턴하는것입니다. 응답을 받은 브라우저는 해당 쿠키를 저장합니다.
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=415EDA48BE181A3396E36125D9FDC293; Path=/; HttpOnly
Content-Type: text/html;charset=utf-8
Content-Length: 144
Date: Wed, 10 Oct 2018 12:53:40 GMT
<html>
<head>
</head>
<body>
<h1>세션 생성 성공</h1>
org.apache.catalina.session.StandardSessionFacade@10bdb1af
</body>
</html>
3. 이후 요청시마다 해당 세션 ID를 HTTP 요청 헤더에 포함하여 요청합니다.
GET http://localhost/boards.jsp HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Accept-Language: ko-KR
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: localhost
Connection: Keep-Alive
Pragma: no-cache
Cookie: JSESSIONID=415EDA48BE181A3396E36125D9FDC293
4. 서버는 요청 헤더의 JSESSIONID 쿠키를 참조하여 자신이 가지고 있는 세션객체를 구분합니다. 예를 들어 해당 세션에 로그인된 사용자 정보등이 담겨있으면 로그인이 되어있는것으로 판단하는 등의 응용이 가능합니다.
세션객체의 메서드
JSP/Servlet 환경에서 세션객체는 javax.servlet.http.HttpSession 타입의 객체입니다. 세션 객체는 다음과 같은 메서드들을 가집니다.
메서드 |
리턴타입 |
설명 |
setAttribute(String name, Obejct value) |
void |
세션에 데이터를 저장합니다. name이 저장할 데이터의 이름이 되고, value에 저장할 값을 지정합니다. Object형이므로 모든 객체를 저장할 수 있습니다. |
getAttribute(String name) |
Object |
세션에 저장한 데이터중 name에 해당하는 값을 리턴합니다. Object형이므로 저장 이전의 원래 타입으로 형변환하여 사용합니다. |
getId() |
String |
브라우저별로 생성되어진 세션을 구분하기 위한 ID를 리턴합니다. |
getCreationTime() |
long |
세션이 생성된 시간을 구합니다. 1970.1.1을 기준으로 몇 ms(1/1000초)가 흘렀는지를 정수값으로 리턴합니다. |
getLastAccessedTime() |
long |
웹브라우저가 가장 최근에 세션에 접근한 시간을 구합니다. 세션에 접근했다는것은 세션이 유효한 페이지에 접근했다는 뜻입니다. 즉 JSP를 기준으로 가장 최근에 page 디렉티브의 session값이 true인 페이지에 접근한 시간을 의미합니다. 1970.1.1을 기준으로 몇 ms(1/1000초)가 흘렀는지를 정수값으로 리턴합니다. |
invalidate() |
void |
세션을 종료합니다. 종료된 세션 객체는 곧 제거되며, 이후에 요청시 새로운 세션이 생성됩니다. |
setMaxInactiveInterval(int interval) |
void |
세션의 유효시간을 초단위로 지정합니다. 유효시간은 가장 최근에 세션에 접근한 이후 유효한 시간입니다. 즉 getLastAccessedTime()메서드를 호출했을때의 시간과 현재 시간 사이의 간격을 의미합니다. 0 또는 음수로 지정하는 경우 invalidate() 메서드를 호출하기 전까지는 세션이 제거되지 않습니다. 그러나 세션 또한 객체이므로 서버의 메모리를 차지하므로 주의해야합니다. |
getMaxInactiveInterval() |
int |
세션의 유효시간을 초단위로 구합니다. |
세션에 관한 정보 출력하기
세션이 생성된 이후에는 세션에 대한 정보를 얻을 수 있습니다.
/getSession.jsp
<%@ page contentType="text/html; charset=utf-8" session="true"%>
<%@ page import="java.util.Date"%>
<html>
<head>
</head>
<body>
세션 ID : <%= session.getId() %>
세션 생성 시간 : <%= new Date(session.getCreationTime()) %>
세션 최근 접근 시간 : <%= new Date(session.getLastAccessedTime()) %>
</body>
</html> |
cs |
세션ID는 세션 객체를 구분하기 위한 ID이고 세션 생성시 간은 세션 객체가 생성된 시점이기 때문에 매번 새로고침하여 호출하여도 변하지 않습니다. 세션 최근 접근 시간은 이전에 세션에 접근했던 시간이므로 새로고침시마다 바뀌는것을 볼 수 있습니다.
세션에 데이터 저장 및 가져오기
세션의 가장 큰 목적은 상태 유지에 있습니다. 즉 HTTP의 상태가 없는 특성을 극복하고자 한 기술이기에 여러가지 데이터를 저장하여 유지할 수 있습니다. login페이지에서 로그인에 성공하면 해당 사용자의 정보 및 로그인 여부를 세션을 생성하여 저장하고 이후 서버의 다른 웹페이지 호출시마다 로그인 여부를 판단하거나 사용자 정보를 얻어올 때 해당 세션을 사용할 수 있을것입니다.
/login.jsp
세션에 데이터를 저장할때에는 setAttribute(String name, Object value) 메서드를 사용합니다.
<%@ page contentType="text/html; charset=utf-8" session="true"%>
<html>
<head>
</head>
<body>
<h1>로그인 페이지</h1>
<%
session.setAttribute("isLogin", true);
%>
</body>
</html> |
cs |
loginCheck.jsp
세션에 저장된 값을 가져올때는 Object getAttribute(String name) 메서드를 사용합니다. Object 타입의 객체를 리턴하므로 원래 타입으로 형변환 하여 사용합니다.
<%@ page contentType="text/html; charset=utf-8" session="true"%>
<html>
<head>
</head>
<body>
<%
Boolean isLogin = (Boolean)session.getAttribute("isLogin");
if(isLogin != null && isLogin){
out.println("<h1>로그인 성공!</h1>");
}else{
out.println("<h1>로그인 실패!</h1>");
}
%>
</body>
</html> |
cs |
로그인 페이지에 접속합니다. 이때 세션이 생성되며, isLogin 값을 true로 저장합니다.
이후 loginCheck.jsp 페이지를 호출하면 로그인에 성공합니다. 만약 login.jsp를 호출하지 않은 상태에서 곧바로 loginCheck.jsp를 호출했다면 로그인에 실패한것으로 판단합니다.
다음글
'Servlet&Jsp' 카테고리의 다른 글
[서블릿/JSP] 세션(session)을 명시적으로 종료시키는 방법 (0) | 2018.12.18 |
---|---|
[서블릿/JSP] Client IP를 알기 위해 request.getRemoteAddr() 사용시 127.0.0.1만 리턴되는 문제 (with Proxy Server) (0) | 2018.11.08 |
[서블릿/JSP] 쿠키(Cookie)의 path 속성으로 전송 URL 지정하기 (1) | 2018.09.20 |
[서블릿/JSP] 쿠키(Cookie)의 domain 속성 설명. 쿠키 전송 범위 설정하기 (0) | 2018.09.15 |
[서블릿/JSP] Servlet/JSP 환경에서 쿠키(Cookie) 사용 방법 (0) | 2018.09.12 |