이전글
HttpSessionListener 리스너
JSP/Servlet 환경에서는 접속한 클라이언트에 대한 정보를
HttpSession
객체에 담아 표현합니다. HttpSession
객체는 HTTP 요청시 생성되었다가 응답시 사라지는 ServletRequest
객체와는 다르게 JSP나 Servlet에 의해 생성된 후 설정된 timeout
에 따라서 제거됩니다.그리고 이
HttpSession
객체가 생성되고 제거될 때 발생되는 이벤트가 HttpSessionEvent
이며, 이 이벤트를 처리하는 리스너가 HttpSessionListener
리스너입니다. 리스너는 다음과 같이 interface로 API가 제공되므로 개발자는 이 리스너를 구현하여 설정으로 등록만 해주면 됩니다.
public interface HttpSessionListener extends EventListener {
/**
* 세션이 생성되었을 때 호출됨.
*/
public void sessionCreated(HttpSessionEvent se);
/**
* 세션이 제거되었을 때 호출됨.
*/
public void sessionDestroyed(HttpSessionEvent se);
} |
cs |
서블릿 컨테이너는
HttpSessionEvent
가 발생한 시점에 자신에게 등록된 HttpSessionListener
구현체가 있는지 확인합니다. 만약 등록된 리스너가 있으면 세션이 생성된 시점에 해당 HttpSessionListener 리스너의 sessionCreated()
를 세션이 제거된 시점에 sessionDestroyed()
를 호출합니다.실습 예제
사용자 로그인시 접속자수를 늘리고 로그아웃시 접속자수를 줄이는 예제를 통해 HttpSessionListener를 구현하는 실습을 해보도록 하겠습니다. 패키지 구성은 다음과 같이 할 것입니다.
LoginUserCounter - HttpSessionListener를 구현한 클래스이며, 세션 생성시 접속자수를 늘려주고 콘솔로 접속자수를 출력하며, 로그아웃시 세션이 제거되는 시점에서 접속자수를 줄여준 후 콘솔로 출력합니다.
web.xml - 구현한 HttpSessionListener 리스너를 등록합니다.
login.jsp - 사용자 id와 비밀번호를 입력하는 jsp 페이지입니다.
main.jsp - login.jsp에서 로그인 버튼을 누르면 넘어오는 페이지로 id와 password를 동일하게 입력한 경우 로그인으로 처리하고 아닌경우 실패로 간주하여 login.jsp로 다시 리다이렉트시킵니다.
logout.jsp - main.jsp의 로그아웃 버튼을 누르면 넘어오는 페이지로 세션을 제거하여 로그아웃처리합니다.
HttpSessionListener 리스너 구현
LoginUserCounter 클래스는
HttpSessionListener
를 구현한 클래스입니다. 세션 생성시 userCount
값을 증가시키로 세션 제거시 userCount
값을 감소시킵니다.
package listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class LoginUserCounter implements HttpSessionListener {
private int userCount;
public void sessionCreated(HttpSessionEvent se) {
++userCount;
System.out.printf("생성된 SESSIONID %s \n", se.getSession().getId());
System.out.printf("로그인된 사용자 수 : %d \n", userCount);
}
public void sessionDestroyed(HttpSessionEvent se) {
--userCount;
System.out.printf("제거된 SESSIONID %s \n", se.getSession().getId());
System.out.printf("로그인된 사용자 수 : %d \n", userCount);
}
} |
cs |
HttpSessionEvent 객체
구현된 리스너를 보면 각각의 메서드에서
HttpSessionEvent
객체가 매개변수로 넘어오는것을 볼 수 있는데, 이 객체는 제거 또는 생성된 HttpSession
객체를 리턴하는 getSession()
메서드를 제공합니다. 위 예제에서는 이를통해 세션ID를 얻어오고 있습니다. 따라서 리스너에서 세션을 조작하는것도 가능합니다.HttpSessionListener 리스너 등록
리스너를 등록하는 방법은 두가지입니다. Servlet 3.0버전 이상인 경우 리스너 구현 클래스에
@WebListener
어노테이션을 붙여주는 방법이 있습니다.
@WebListener
public class LoginUserCounter implements HttpSessionListener {
private int userCounter;
... |
cs |
기본적으로는
web.xml
의 <listener>
태그를 통해 등록하는 방법이 있습니다. 등록시에는 패키지명까지 입력해줍니다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<listener>
<listener-class>listener.LoginUserCounter</listener-class>
</listener>
</web-app> |
cs |
위 두가지 방법중 한가지 방법으로 등록설정은 끝이며, 서블릿 컨테이너가 최초에 기동될때 설정을 읽어들여 리스너 객체를 컨테이너 내부에 생성하고 이벤트 발생시 알맞는 메서드를 호출합니다.
나머지 JSP 작성
이제 JSP를 작성할 차례입니다.
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
<form action="main.jsp" method="post">
id : <input type="text" name="id"><br>
password : <input type="password" name="password"><br>
<input type="submit" value="로그인">
</form>
</body>
</html> |
cs |
main.jsp
id와 비밀번호를 같게 입력하면 로그인으로 처리하고 아니면 다시 로그인페이지로 이동시킵니다. 로그인에 성공하면 화면에 로그아웃 버튼을 표시합니다. 상단의 page 디렉티브의 session 속성이 false인것을 볼 수 있는데, 이는 JSP 페이지에서 이 값을 false로 명시하지 않는 경우 기본적으로 세션을 생성하기 때문입니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<%
request.setCharacterEncoding("utf-8");
String id = request.getParameter("id");
String password = request.getParameter("password");
if(id.equals(password)) {
//로그인 성공시 세션 생성
HttpSession session = request.getSession();
session.setAttribute("id", id);
}else {
//로그인 실패시 로그인 페이지로 리다이렉트
response.sendRedirect("login.html");
}
%>
<html>
<head>
<meta charset="utf-8">
<title>메인페이지</title>
</head>
<body>
<h1><%= id %> 님 로그인 되었습니다.</h1>
<a href='logout.jsp'>로그아웃</a>
</body>
</html> |
cs |
logout.jsp
현재 생성 되어 이는 세션객체를
invalidate()
메서드로 제거합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" session="false"%>
<html>
<head>
<title>로그아웃</title>
</head>
<body>
<%
HttpSession session = request.getSession(false);
String id = (String)session.getAttribute("id");
session.invalidate();
%>
<h1><%= id %> 로그아웃됨 </h1>
</body>
</html> |
cs |
테스트
서버를 시작하고 login.jsp로 이동합니다. id와 password를 동일하게 입력하고 로그인 버튼을 누릅니다.
로그인에 성공하며 main.jsp로 이동됩니다.
이클립스 콘솔창을 보니 로그인된 사용자 수가 1인것을 볼 수 있습니다.
이번에는 새로운 브라우저를 띄우로 login.jsp로 접속합니다. 크롬이었다면 익스플로러로 반대라면 크롬을 열고 똑같이 로그인합니다.
로그인에 성공하면 콘솔창에 로그인한 사용자수가 2로 증가합니다.
이제 각각 로그아웃 버튼을 눌러 로그아웃합니다.
로그인된 사용자 수가 줄어드는것을 볼 수 있습니다.