* 본 글은 [뉴렉처]의 Servlet&JSP 프로그래밍 강의를 듣고 정리한 글입니다.
2020 Servlet&JSP 프로그래밍
www.youtube.com
Session 객체로 상태 값 저장하기 (+ Application 객체와의 차이점)
Session 객체
- Application 객체와 같이, 상태를 저장하거나 앞에서 다룬 결과를 잠깐 저장하기 위해 사용하는 객체
- Application 객체와 사용법이 같음
- Application 객체의 사용법
ServletContext application = request.getServletContext( );
...
int x = (Integer)application.getAttribute("value");
...
String operator = (String)application.getAttribute("op");
...
application.setAttribute("value", v);
application.setAttribute("op", op);
- Session 객체의 사용법
HttpSession session = request.getSession( );
...
int x = (Integer)session.getAttribute("value");
...
String operator = (String)session.getAttribute("op");
...
session.setAttribute("value", v);
session.setAttribute("op", op);
Application 객체와 Session 객체의 차이점
- Application 객체
- 서블릿이 애플리케이션 전역에서 사용할 수 있는 공간
- Session 객체
- 서블릿이 세션 범주 내에서 사용할 수 있는 공간
- Session = 현재 접속한 사용자
- 크롬은 여러 개의 창을 띄워도 어떤 창도 끊기지 않음 (언제 접속하더라도 모두 현재 접속한 사용자로 인식한다는 뜻)
- 크롬은 하위 흐름을 갖고 있는 스레드로 여러 개의 창을 띄움
- 스레드는 프로세스의 자원을 다같이 공유함
- 웹서버에 요청하면 같은 프로세스를 요청한 것으로 인식되기 때문에 같은 사용자/Session으로 인식됨
- 그러면 웹 서버는 현재 사용자(Session)를 어떻게 구분할까?
웹 서버가 현재 사용자(Session)를 구별하는 방법
- 클라이언트는 브라우저를 이용해 서버에 요청
- 서버에는 사용자의 요청을 수반한 프로그램을 처리
- 그 프로그램에서 다른 서블릿에 공유하고 싶은 내용을 저장할 수 있는 공간에 Application과 Session이 존재
- Application
- 애플리케이션 전역에서 사용 가능한 공간
- Session
- 사용자마다 저장할 수 있는 공간
- SID(Session ID)를 갖고 있는 사용자만 Session에 값을 저장할 수 있음
- SID가 다르면, 사용자가 다르다고 봄
- Application
- WAS(Web Application Server)가 세션 ID에 맞는 사용자 저장소를 구별하는 과정
- 1) 클라이언트가 서버에 처음 요청을 전달할 땐 해당 브라우저는 SID가 없음
- Application 이용 가능 / Session 이용 불가능
- 2) 서버가 응답을 보낼 때 WAS가 클라이언트에 SID를 하나 발급해줌 > Session에 해당 아이디에 맞는 공간이 만들어짐
- WAS는 같은 브라우저에게 항상 같은 SID를 발급함
- 3) 클라이언트가 서버에 두 번째 요청을 전달할 땐 이전에 받은 SID를 갖고 있음
- Application와 Session 모두 이용 가능
- 브라우저는 항상 SID를 갖고 다님
- 브라우저를 닫으면 SID가 사라짐 > Session 값도 사라짐
- But, 브라우저가 달라지면 SID가 없으니까 첫 번째 요청에는 Session 이용 불가능 > 서버가 클라이언트에 SID 발급 > 두 번째 요청부터는 Session 이용 가능
- 1) 클라이언트가 서버에 처음 요청을 전달할 땐 해당 브라우저는 SID가 없음
- SID 확인 방법: 브라우저마다 SID가 다름
- 크롬
- 엣지
- SID를 복사해 요청하면 WAS는 같은 사용자로 인식
- 이를 해결하기 위해 WAS들은 다양한 방법을 활용
- 예: MS는 SID가 계속 바뀜
- 이를 해결하기 위해 WAS들은 다양한 방법을 활용
Session 메소드
- void setAttribute(String name, Object value)
- 지정된 이름으로 객체를 설정
- Object getAttribute(String name)
- 지정한 이름의 객체를 반환
- void invalidate( )
- Session 저장소를 비울 때 사용하는 메소드 (setAttribute( )메소드로 설정했던 것들을 지움)
- 세션에서 사용되는 객체들을 바로 해제 (사용자 요청이 계속 올지 아닐지 알 수 없으니까)
- void setMaxInactiveInterval(int interval)
- 세션 타임아웃을 정수(초)로 설정
- 세션 타임아웃: 이 시간 동안 사용자 요청이 안 오면 Session 저장소를 지우도록 제한시간을 주는 것
- 기본 타임아웃은 30분이지만, 개별적으로 변경할 수도 있음
- 1초 남은 상태에서 새로운 요청이 오면 타임아웃이 다시 30분으로 리셋되면서 다음 타임아웃이 진행됨
- 타임아웃이 경과되는 순간 해당 타임아웃의 SID를 갖고 있는 사용자 요청이 오면 그 요청은 새로운 사용자 요청으로 인식됨
- 유효하지 않은 SID가 되었기 때문에 해당 Session의 값들은 메모리에서 수거됨
- boolean isNew( )
- 세션이 새로 생성되었는지를 확인
- long getCreationTime( )
- 세션이 시작된 시간을 반환
- 1970년 1월 1일을 시작으로 하는 밀리초
- long getLastAccessedTime( )
- 세션이 마지막으로 요청된 시간을 반환
- 1970년 1월 1일을 시작으로 하는 밀리초
메소드 | 리턴타입 | 설명 |
setAttribute(String name, Object value) | void | 지정한 이름으로 객체를 설정 |
getAttribute(String name) | Object | 지정한 이름의 객체를 반환 |
invalidate( ) | void | • Session 저장소를 비울 때 사용하는 메소드 (setAttribute( )메소드로 설정했던 것들을 지움) • 세션에서 사용되는 객체들을 바로 해제 (사용자 요청이 계속 올지 아닐지 알 수 없으니까) |
setMaxInactiveInterval(int interval) | void | • 세션 타임아웃을 정수(초)로 설정 • 세션 타임아웃: 이 시간 동안 사용자 요청이 안 오면 Session 저장소를 지우도록 제한시간을 주는 것 • 기본 타임아웃은 30분이지만, 개별적으로 변경할 수도 있음 • 1초 남은 상태에서 새로운 요청이 오면 타임아웃이 다시 30분으로 리셋되면서 다음 타임아웃이 진행됨 • 타임아웃이 경과되는 순간 해당 타임아웃의 SID를 갖고 있는 사용자 요청이 오면 그 요청은 새로운 사용자 요청으로 인식됨 ◦ 유효하지 않은 SID가 되었기 때문에 해당 Session의 값들은 메모리에서 수거됨 |
isNew( ) | boolean | 세션이 새로 생성되었는지를 확인 |
getCreationTime( ) | long | • 세션이 시작된 시간을 반환 • 1970년 1월 1일을 시작으로 하는 밀리초 |
getLastAccessedTime( ) | long | • 세션이 마지막으로 요청된 시간을 반환 • 1970년 1월 1일을 시작으로 하는 밀리초 |
Session 사용하기
- Calc2.java
- 값 v를 저장하기 위해 request의 getSession( )메소드를 사용하고, HttpSession형 변수에 저장
- HttpSession session = request.getSession( );
- 변수 session에 v과 op의 값을 저장하기 위해 setAttribute(name, object)메소드 사용
- session.setAttribute("value", v); session.setAttribute("op", op);
- 값 v를 저장하기 위해 request의 getSession( )메소드를 사용하고, HttpSession형 변수에 저장
package com.newlecture.web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/calc2")
public class Calc2 extends HttpServlet {
@Override
protected void service(HttpServletRequest request
, HttpServletResponse response)
throws ServletException, IOException
{
ServletContext application = request.getServletContext();
HttpSession session = request.getSession();
//response의 인코딩 방식 지정
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String v_ = request.getParameter("v");
String op = request.getParameter("operator");
//기본값 처리
int v = 0;
if(!v_.equals("")) {v = Integer.parseInt(v_);}
//값을 계산
if(op.equals("=")) {
int x = (Integer)application.getAttribute("value");
int y = v;
String operator = (String)application.getAttribute("op");
int result = 0;
if(operator.equals("+")) {
result = x + y;
} else {
result = x - y;
}
response.getWriter().printf("계산 결과는 %d\n", result);
}
//값을 저장
else {
// application.setAttribute("value", v);
// application.setAttribute("op", op);
session.setAttribute("value", v);
session.setAttribute("op", op);
}
}
}
- calc2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>계산기 웹 프로그램</title>
</head>
<body>
<form action="calc2" method="post">
<div>
<p>계산할 값을 입력하세요.</p>
</div>
<div>
<label>입력 : </label>
<input type="text" name="v"/>
</div>
<div>
<input type="submit" name="operator" value="+">
<input type="submit" name="operator" value="-">
<input type="submit" name="operator" value="=">
</div>
</form>
</body>
</html>
'☕ Java 웹 프로그래밍 > Servlet & JSP' 카테고리의 다른 글
[Servlet&JSP] Cookie의 path 옵션: 해당 path 요청일 때만 쿠키 읽기 (0) | 2023.06.01 |
---|---|
[Servlet&JSP] Cookie로 상태 값 유지하기 (0) | 2023.06.01 |
[Servlet&JSP] Application 객체로 상태 값 저장하기 (0) | 2023.05.29 |
[Servlet&JSP] 8일차 | 상태 유지를 필요로 하는 경우와 구현의 어려움 (0) | 2023.05.28 |
[Servlet&JSP] 배열 형태로 입력 데이터 받기 (0) | 2023.05.28 |