🍁session 객체, application 객체
session 객체
session 객체는 클라이언트(브라우저)의 세션 정보(접속부터 종료까지의 개인 정보)를 저장하고 관리하는 객체이다.
즉, session 객체는 고객(개인 방문자)에 대한 모든 개인 정보를 관리하는 객체이다.
로그인 작업이 session 객체에서 이루어진다.
application 객체
- 웹 사이트 == 웹 응용 프로그램 == 웹 애플리케이션
웹 사이트는 웹에서 돌아간다는 의미에서 하나의 웹 응용 프로그램이라고 하며, 웹 애플리케이션이라고도 부른다.
application 객체는 애플리케이션(웹 사이트)의 전체적인 정보를 관리하고 조작하는 객체이다.
Map 형태의 내장 객체
request, session, pageContext, application
- void setAttribute(String key, Object value)
- Object getAttribute(String key)
위 객체에는 내부에 Map형태로 데이터를 저장하는 공간이 있다.
변수 저장과 출력
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//session 변수
session.setAttribute("a", 10); //session 객체에 a 변수 저장
//application 변수
application.setAttribute("b", 20); //application 객체에 b 변수 저장
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="http://pinnpublic.dothome.co.kr/cdn/example-min.css">
<style>
</style>
</head>
<body>
<h1>session</h1>
<div>a: <%= session.getAttribute("a") %></div>
<h1>application</h1>
<div>b: <%= application.getAttribute("b") %></div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://pinnpublic.dothome.co.kr/cdn/example-min.js"></script>
<script>
</script>
</body>
</html>
setAttribute 메서드는 세션 객체에 변수를 저장할 수 있게 해 준다. 이때 변수는 엄밀히 말하면 Hash Map에 저장한 value이다.
session 객체와 application의 내부 구조가 같기 때문에 데이터를 넣거나 출력할 때 같은 코드를 사용할 수 있다.
브라우저와 웹 페이지의 연결
HTTP 프로토콜의 특징
- 비연결을 지향한다.
브라우저에서 Naver를 띄워서 Naver 서버에 접속하려고 한다.
Naver에 접속을 하면 Naver는 시작 페이지를 찾아서 사용자에게 돌려준다. 페이지를 돌려주는 작업이 끝나면 브라우저와 Naver의 연결이 끊겨버린다.
그래도 상관없는 이유는 사용자는 바로 해당 페이지를 보는 게 아니라 복사된 페이지를 보게 되기 때문이다.
연결을 유지하고 있는 상태에 비용이 들어가기 때문에 연결을 끊는 것이다. 이를 컴퓨터 입장에서 보면 메모리나 CPU를 더 많이 잡아먹는 셈이다. 그런데 웹을 보고 있는 중에는 연결하고 있을 필요가 없으므로 연결을 끊어도 된다.
그래서 현재 Naver에 들어가 있지만, Naver와 연결되어 있지는 않은 상태이다. 그러다 Naver의 어떤 페이지에 들어가면 다시 잠깐 Naver와 연결이 되었다가 해당 페이지에 들어가는 순간 다시 끊어진다.
그리고 연결이 끊겨 있다는 건 Naver가 사용자를 모른다는 걸 의미한다. 그래서 사용자에 대한 관리가 이루어지지 않는다. 이를 해결하기 위한 여러 도구가 있으므로 안정화가 된 상태지만, 아직 깔끔하게 해결되지는 않은 상태이다. 이 특성이 웹이 어렵게 느껴지는 이유이기도 하다.
타이머 객체
사용자가 접속을 해서 페이지를 돌려받기 직전에 웹 서버에서 메모리에 객체를 하나 만들어 둔다. 만약 A가 접속을 했다면 객체 안에 A를 인식할 수 있는 데이터를 저장한다.
브라우저가 페이지를 가져가고 연결이 끊긴다. 이제 A가 페이지를 보고 있는지 안 보고 있는지를 모른다. 그런데 이 객체에는 특징이 있는데, 내부에 시간이 줄어드는 타이머가 있다는 점이다. 이때 타이머의 시간을 정해줄 수 있으며, 보통은 30분으로 되어 있다. 이 타이머는 만들어지자마자 줄어들기 시작한다.
15분이 지났다고 하자. 그리고 또 다른 페이지를 링크하면 새로운 페이지를 링크할 때 15분으로 줄어든 타이머가 30분으로 reset 된다. 타이머는 0이 되면 소멸하며, 사용자가 나간 즉시에 나갔는지는 모르지만, 타이머가 살아 있다면 A가 아직 페이지에 접속 중이라고 짐작할 수 있다.
session 객체의 역할이 바로 이 객체이다. session 객체는 접속한 사람 한 명 당 하나씩 생기므로, session 객체로 고객에 대한 정보를 관리한다. 그리고 application 객체는 사람 당 하나씩 생기는 게 아니라 전체를 통틀어 하나만 생긴다.
자바로 치면 application은 static 변수, session은 전역 변수로 생각하면 된다.
방문 카운트
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//session 변수
session.setAttribute("a", 10); //session 객체에 a 변수 저장
//application 변수
application.setAttribute("b", 20); //application 객체에 b 변수 저장
//방문 카운트
if (session.getAttribute("count") == null) {
session.setAttribute("count", 1);
} else {
//count = count + 1
session.setAttribute("count", (int)session.getAttribute("count") + 1); //Down Casting, 페이지 실행할 때마다 누적
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="http://pinnpublic.dothome.co.kr/cdn/example-min.css">
</head>
<body>
<h1>session</h1>
<div>a: <%= session.getAttribute("a") %></div>
<h1>application</h1>
<div>b: <%= application.getAttribute("b") %></div>
<h1>방문 카운트</h1>
<div>count: <%= session.getAttribute("count") %></div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://pinnpublic.dothome.co.kr/cdn/example-min.js"></script>
</body>
</html>
session 객체는 사이트 전역 변수이다.
지역 변수로 카운트를 하지 않는 이유는 페이지가 종료되면 소멸되기 때문이다.
페이지를 종료하더라도 session 객체가 죽지 않고 살아 있기 때문에 방문 카운트를 할 수 있다. 또한, 이를 다른 페이지에 추가하더라도 카운트가 되는 것을 볼 수 있다.
이는 session 객체의 중요한 특징 중에 하나이다. session 객체는 독립적으로 관리되기 때문에 사이트 내에서 전달 과정 없이 접근할 수 있는 데이터가 된다.
그래서 일종의 session 객체는 사이트 전역 변수라고 생각하면 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//session 변수
session.setAttribute("a", 10); //session 객체에 a 변수 저장
//application 변수
application.setAttribute("b", 20); //application 객체에 b 변수 저장
//방문 카운트
if (session.getAttribute("count") == null) {
session.setAttribute("count", 1);
} else {
//count = count + 1
session.setAttribute("count", (int)session.getAttribute("count") + 1); //Down Casting, 페이지 실행할 때마다 누적
}
//방문 카운트
if (application.getAttribute("count") == null) {
application.setAttribute("count", 1);
} else {
//count = count + 1
application.setAttribute("count", (int)application.getAttribute("count") + 1); //Down Casting, 페이지 실행할 때마다 누적
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="http://pinnpublic.dothome.co.kr/cdn/example-min.css">
</head>
<body>
<h1>session</h1>
<div>a: <%= session.getAttribute("a") %></div>
<h1>application</h1>
<div>b: <%= application.getAttribute("b") %></div>
<h1>방문 카운트</h1>
<div>count: <%= session.getAttribute("count") %></div>
<h1>방문 카운트</h1>
<div>count: <%= application.getAttribute("count") %></div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://pinnpublic.dothome.co.kr/cdn/example-min.js"></script>
</body>
</html>
다른 브라우저에서 확인해 보니 session 객체의 count가 다르게 나온다. 두 브라우저는 같은 페이지에 들어가더라도 다른 사용자로 보기 때문이다. 반면에 application을 모두 같은 사용자로 본다.
개인의 데이터면 session 객체, 공용의 데이터면 application 객체를 이용하면 된다. 보통 접속한 사용자가 공통으로 사용할 값은 거의 없기 때문에 session 객체의 사용 빈도수가 높다.
🍁session 객체
(현재) 세션 정보
<%@page import="java.util.Calendar"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="http://pinnpublic.dothome.co.kr/cdn/example-min.css">
<style>
</style>
</head>
<body>
<h1>세션 (Session)</h1>
<div class="list">
<div><a href="ex15_set.jsp">세션값 저장하기</a></div>
<div><a href="ex15_del.jsp">세션값 삭제하기</a></div>
<div><a href="ex15_reset.jsp">세션 초기화</a></div>
<div><a href="ex15_interval.jsp">세션 만료 시간 설정하기</a></div>
</div>
<hr>
<h2>(현재) 세션 정보</h2>
<div>
Session ID:
<%= session.getId() %>
</div>
<div>
Session Create Time:
<%
Calendar time = Calendar.getInstance();
time.setTimeInMillis(session.getCreationTime());
out.println(String.format("%tF %tT", time, time));
%>
<%= session.getCreationTime() %>
</div>
<div>
Session Max Inactive Interval:
<%= session.getMaxInactiveInterval() %>
</div>
<div>
Session inNew:
<%= session.isNew() %>
</div>
<div>
Session Data:
<%
if (session.getAttribute("data") != null) {
out.println(session.getAttribute("data"));
} else {
out.println("데이터 없음");
}
%>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://pinnpublic.dothome.co.kr/cdn/example-min.js"></script>
<script>
</script>
</body>
</html>
getId: 난수의 숫자와 영어가 혼합된 고유한 문자로, 서버 메모리 상의 수많은 Session 객체가 있는데, 중복이 되지 않도록 할당한다. 내부에서 톰캣이 관리하는 용도로만 사용하므로 DB에 저장하지 않는다.
getCreationTime: Session 객체가 언제 만들었는지를 나타낸다. 만약 새롭게 Session 객체를 만들고 싶다면 열려 있는 해당 브라우저를 모두 종료한 뒤에 다시 실행해야 한다.
getMaxInactiveInterval: 1800초(30분)로, 타이머의 만료 시간이다.
isNew: 지금 만든 session인지, 아까 만들었는데 아직도 사용하고 있는 session인지를 알려준다. 새롭게 만들어진 session 객체가 아니므로 false를 반환한다.
getAttribute: 들어간 데이터가 있는지 없는지를 나타낸다. 데이터가 없기 때문에 false(데이터 없음)를 반환한다.
세션값 저장하기
<h1>세션값 저장하기</h1>
<%
session.setAttribute("data", "Isaac");
%>
<div>
<a href="ex15_session.jsp">돌아가기</a>
</div>
세션값을 저장하면 'Isaac'이 저장된다.
세션값 삭제하기
<h1>세션값 삭제하기</h1>
<%
session.removeAttribute("data");
%>
세션에 들어있던 데이터가 사라진다.
세션 초기화
현재 사용하는 세션이 유효하지 않게 만든다.
세션을 새로 만드므로 isNew가 true가 되고, 세션 안에 있는 데이터가 사라진다.
세션 만료 시간
<h1>세션 만료 시간</h1>
<%
session.setMaxInactiveInterval(30);
%>
세션이 만료되면 완전히 초기화된다.
그렇다고 초기화를 피하고자 Interval을 늘리는 건 적합하지 않다. Session에 사용자의 메모리가 서버 메모리에 계속 저장되어 공간이 낭비되기 때문이다.