이전글


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를 구현하는 실습을 해보도록 하겠습니다. 패키지 구성은 다음과 같이 할 것입니다.


LoginUserCounterHttpSessionListener를 구현한 클래스이며, 세션 생성시 접속자수를 늘려주고 콘솔로 접속자수를 출력하며, 로그아웃시 세션이 제거되는 시점에서 접속자수를 줄여준 후 콘솔로 출력합니다.
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로 증가합니다.


이제 각각 로그아웃 버튼을 눌러 로그아웃합니다.



로그인된 사용자 수가 줄어드는것을 볼 수 있습니다.


블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,