[서블릿/JSP] HttpSessionAttributeListener 리스너로 세션 Attribute 변경시 이벤트 처리하기
Servlet&Jsp 2019. 7. 18. 14:56이전글
HttpSession의 attribute
HttpSession객체는 세션에 값을 저장하기 위한 용도로 attribute를 조작할 수 있는 두가지 메서드를 가지고 있습니다.|
public void setAttribute(String name, Object value) //attribute 새로 추가 또는 변경
public void removeAttribute(String name) //attribute 제거 |
cs |
setAttribute()는 새로운 attribute를 추가하거나 변경할 때 사용합니다. 같은 name에 대해 새로운 value를 지정하면 변경된것으로 처리됩니다. removeAttribute()의 경우 name으로 지정한 attribute 값을 제거합니다. HttpSessionAttributeListener 리스너
HttpSessionAttributeListener를 이용하면 HttpSession객체의 attribute가 새로 추가되거나 변경되거나 제거되었을때 발생하는 HttpSessionBindingEvent이벤트를 처리할 수 있습니다.HttpSessionAttributeListener는 다음과 같이 인터페이스로 제공되므로 각 이벤트를 처리하고 싶은 경우 리스너를 구현하고 서블릿컨테이너에 설정을 통해 등록해주어야 합니다.|
package javax.servlet.http;
import java.util.EventListener;
public interface HttpSessionAttributeListener extends EventListener {
/**
* 세션객체에 setAttribute()를 통해 새로운 객체가 등록되었을 때 호출
*/
public void attributeAdded(HttpSessionBindingEvent event);
/**
* removeAttribute()를 통해 세션객체에 저장된 객체가 제거되었을 때 호출
*/
public void attributeRemoved(HttpSessionBindingEvent event);
/**
* setAttribute()를 통해 기존에 저장된 객체가 새로운 객체로 저장되었을 때 호출
*/
public void attributeReplaced(HttpSessionBindingEvent event);
} |
cs |
구현된 리스너를
web.xml의 <listener> 태그나 @WebListener 어노테이션을 통해 등록해두면 서블릿 컨테이너가 시작될때 리스너 객체를 생성해두고 이벤트가 발생했을때 서블릿 컨테이너에서 각 행위에 맞는 메서드를 호출해줍니다.
HttpSessionBindingEvent
앞의
HttpSessionAttributeListener 리스너 명세를 보면 매개변수로 HttpSessionBindingEvent 객체가 넘어오는것을 볼 수 있습니다. 이 이벤트 객체는 다음의 세가지 메서드를 제공하므로 리스너 내에서 응용이 가능합니다.public HttpSession getSession() - 이벤트가 발생한 세션 객체를 리턴합니다.
public String getName() - 변경되거나 삭제된
attribute의 name이 문자열로 리턴됩니다.public Object getValue() - 변경되거나 삭제된
attribute값이 Object타입으로 리턴됩니다.실습 예제
HttpSessionAttributeListener 동작 방식을 이해하기 위해 세션의 attibute를 조작하면서 리스너가 어떤식으로 동작하는지 확인해보도록 하겠습니다. 패키지는 다음과 같이 구성합니다.TestSessionAttrListener - HttpSessionAttributeListener 구현 클래스addAttr.jsp - 세션에 attribute를 추가 또는 변경하는 jspremoveAttr.jsp - 세션에 attribue를 제거하는 jspHttpSessionAttributeListener 구현
이벤트별 호출 메서드에
세션ID와 변경된 attribute의 name과 value를 콘솔에 출력되도록 하였습니다. |
package listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener
public class TestSessionAttrListener implements HttpSessionAttributeListener {
public TestSessionAttrListener() {
System.out.println("HttpSessionAttributeListener 리스너 생성");
}
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.printf("SESSIONID : %s \n", event.getSession().getId());
System.out.printf("세션에 attribute 추가됨 name : %s attr : %s \n", event.getName(), event.getValue());
}
public void attributeRemoved(HttpSessionBindingEvent event) {
System.out.printf("SESSIONID : %s \n", event.getSession().getId());
System.out.printf("세션에서 attribute 제거됨 name : %s attr : %s \n", event.getName(), event.getValue());
}
public void attributeReplaced(HttpSessionBindingEvent event) {
System.out.printf("SESSIONID : %s \n", event.getSession().getId());
System.out.printf("세션에서 attribute 변경됨 name : %s attr : %s \n", event.getName(), event.getValue());
}
} |
cs |
리스너 등록
클래스 상단에
@WebListener 어노테이션이 보이는데 이는 해당 클래스를 리스너로 등록해주는 설정입니다. 서블릿 컨테이너가 최초에 기동되는 시점에 이 어노테이션을 보고 리스너 객체로 등록할것입니다.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.TestSessionAttrListener</listener-class>
</listener>
</web-app> |
cs |
addAttr.jsp 작성
클라이언트에서 넘겨준
request param을 읽어 해당 name과 value를 attribute로 세팅하는 JSP입니다.|
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String name = request.getParameter("name");
String attr = request.getParameter("attr");
session.setAttribute(name, attr);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>attr 추가 및 변경</title>
</head>
<body>
<h1>세션 Attribute 추가 또는 변경됨</h1>
</body>
</html> |
cs |
removeAttr.jsp 작성
클라이언트에서 넘겨준
request param을 읽어 해당 name에 해당하는 attribute를 제거하는 JSP입니다. |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String name = request.getParameter("name");
session.removeAttribute(name);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>attr 제거</title>
</head>
<body>
<h1>세션 Attribute 제거됨</h1>
</body>
</html> |
cs |
테스트
예제 작성이 모두 끝났으면 톰캣 서버를 시작합니다. 서버를 시작하는 과정에서
console에 리스너가 생성되었다는 로그를 볼 수 있습니다.attribute 추가
아래 URL을 이용하여 age라는 이름으로 30이라는 값을 추가해봅니다.
http://localhost:8080/servletTest/addAttr.jsp?name=age&attr=30
콘솔창을 확인해보니 추가이벤트가 발생했다는것을 알 수 있습니다.
attribute 변경
이전에 호출했던 URL에서 쿼리스트링 끝의 attr값만 50으로 바꾸어줍니다.
http://localhost:8080/servletTest/addAttr.jsp?name=age&attr=40
그런데 변경 이벤트에서 찍힌 attr값은 그대로 30입니다. 즉 변경 이벤트에서
getValue()는 변경 이전의 값을 리턴한다는것을 알 수 있습니다.attribute 제거
다음의 URL을 통해 세션에서 age 속성을 제거해보겠습니다.
http://localhost:8080/servletTest/removeAttr.jsp?name=age
제거 이벤트가 발생한것을 확인합니다.