Servlet Listener : 웹 컨테이너가 관리하는 LifeCycle 사이에 발생하는 이벤트를 감지하여, 이벤트 발생 시 그에 대한 일련의 로직을 처리하는 인터페이스

간단하게 사용하는 경우는 이런 것들이 있다.
Context 변경이 발생하는 경우 (→ 톰캣 컨테이너 자체에 리스너 연결)
Session 객체에 변경이 발생하는 경우 (→ 세션에서 발생 가능한 이벤트)
Request 객체에 변경이 발생하는 경우 (→ request 관련 이벤트)
index.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1 align="center">Listener</h1>
<ul>
<li><a href="context">context listener test</a></li>
<li><a href="session">session listener test</a></li>
</ul>
</body>
</html>
이렇게 두고 리스너들에 대해 알아보자.
ContextListener
import jakarta.servlet.ServletContextAttributeEvent;
import jakarta.servlet.ServletContextAttributeListener;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
@WebListener
public class ContextListener implements ServletContextListener, ServletContextAttributeListener {
public ContextListener() {
System.out.println("context listener 인스턴스 생성");
}
@Override
public void attributeAdded(ServletContextAttributeEvent event) {
System.out.println("context attribute added");
System.out.println("event.getName() = " + event.getName());
}
@Override
public void attributeReplaced(ServletContextAttributeEvent event) {
System.out.println("context attribute replaced");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent event) {
System.out.println("context attribute removed");
}
}
위 코드에서 인터페이스로 되어 있는 ServletContextListener
웹 애플리케이션의 시작과 종료 시 자동 발생하는 이벤트로, Context 생성/소멸 및 Application 생성/소멸 시점에 로직을 처리한다.
ServletContextListener 의 메소드들
contextInitialized (ServletContextEvent e) : voidcontextDestoryed (ServletContextEvent e) : void하지만 ContextListener에서 구현은 하지 않았다. 자동으로 작동하는 것이기 때문
attributeAdded (ServletContextAttributeEvent e) : voidattributeRemoved (ServletContextAttributeEvent e) : voidattributeReplaced (ServletContextAttributeEvent e) : void실행하면 일단은 기본적으로 이렇게 된다.

파랑 사각형의 Session은 이미 코드는 적어놨기 때문에 나오는 것이니 신경 안 써도 괜찮다.
ContextListenerTestServlet
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/context")
public class ContextListenerTestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("context listener 확인용 서블릿");
// context는 실행하자마자 created되고 그것을 컨텍스트 전용 이벤트가 볼 수 있다. ContextListener는 그것을 위해 만듦
ServletContext context = req.getServletContext();
context.setAttribute("test", "value");
context.setAttribute("test2", "value");
context.setAttribute("test2", "value2"); // test2의 value 수정해보기
context.removeAttribute("test"); // 처음 넣었던 것을 test 를 지우는 이벤트 메소드
}
}
jsp 화면에서 context listener test 링크를 눌렀을 때 실행 결과

SessionListener
import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionAttributeListener;
import jakarta.servlet.http.HttpSessionBindingEvent;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
@WebListener
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {
public SessionListener() {
System.out.println("SessionListener 인스턴스 생성");
}
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session created");
System.out.println("생성된 session id : " + se.getSession().getId());
System.out.println("session 객체 타입 : " + se.getSession().getClass().getName());
}
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
System.out.println("session attribute added");
System.out.println("session 추가된 attribution " +event.getName() + ", " + event.getValue());
}
}
HttpSessionListener,HttpSessionAttributeListener속의 메소드들
HttpSessionListener
HTTP session의 생성 및 소멸 시에 작동하는 이벤트로, HttpSession 객체가 생성되거나 소멸되는 시점에 로직을 처리한다.
Method
sessionCreated (HttpSession e): void
→ Session 생성 시 실행
sessionDestoryed (HttpSession e): void
→ Session 무효화 될 때 실행
HttpSessionListener의 메소드 2개는 자동으로 실행되기에
HttpSessionAttributeListener의 메소드들만 구현해봤다.
HttpSessionAttributeListener
Session에 대한 속성의 값이 변경될 경우 발생하는 이벤트로, HttpSession에 대한 속성 값이 변경될 경우 로직을 처리한다.
Method
attributeAdded (HttpSessionBindingEvent e): void
→ Session에 새로운 속성 값이 추가될 때 실행
attributeRemoved (HttpSessionBindingEvent e): void
→ Session에 속성 값이 제거될 때 실행
attributeReplaced (HttpSessionBindingEvent e): void
→ Session에 속성 값이 변경될 때 실행
SessionListenerServlet
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/session")
public class SessionListenerServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
System.out.println("서블릿에서 session 출력 : " + session.getClass().getName());
session.setAttribute("userName", "hongggildong");
session.setAttribute("age", 20);
session.setAttribute("gender", "M");
session.setAttribute("userName", "hong");
session.setAttribute("user", new UserDTO("Honggildong", 20));
session.removeAttribute("user");
session.invalidate();
}
}
UserDTO
import jakarta.servlet.http.HttpSessionBindingEvent;
import jakarta.servlet.http.HttpSessionBindingListener;
/* 설명. HttpSessionBindingListener는 해당 클래스에 리스너를 추가해야 한다. */
public class UserDTO implements HttpSessionBindingListener {
private String name;
private int age;
public UserDTO() {
}
public UserDTO(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "UserDTO{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("UserDTO가 담김");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("UserDTO가 제거됨");
}
}
- HttpSessionBindingListener
- 현재 Session에 객체가 추가되거나 해제될 때 발생하는 이벤트로, 사용자의 현재 Session에 바인딩 되거나 해제될 객체가 발생할 경우 로직을 수행한다.
- Method
valueBound (HttpSessionBindingEvent e): void
→ 객체가 Session에 연결될 때 실행valueUnBound (HttpSessionBindingEvnet e): void
→ 객체가 Session으로부터 연결이 해제될 때 실행
(참고)
HttpSessionAttributeListener와HttpSessionBindingListener의 차이
- HttpSessionAttributeListener : 세션에 어떤 속성이 추가/수정/삭제되는 이벤트가 발생한 경우
- HttpSessionBindingListener : 자신이 세션에 속성으로 추가/삭제된 경우
실행결과
위의 파랑 사각형에서 SessionListener 의 기본생성자가 호출된 것은 봤을 것이다.
일단 실행했을 때는 이런 내용들이 출력된다.

jsp 화면에 있는 SessionListener 링크를 누르면 아래 사진처럼 출력된다.

예제는 없지만 추가 Listener 들
HttpSessionActivationListenersessionDidActivate (HttpSessionEvent e) : void
→ Session 활성화 될 때
sessionWillPassivate (HttpSessionEvent e) : void
→ Session 비활성화 되려고 할 때
ServletRequestListenerrequestInitialized (ServletRequestEvent e) : void
→ request 생성 시 작동
requestDestroyed (ServletRequestEvent e) : void
→ request 소멸 시 작동
ServletRequestAttributeListenerattributeAdded (ServletRequestAttributeEvent e) : void
→ request에 새로운 속성 값이 추가될 때 실행
attributeRemoved (ServletRequestAttributeEvent e) : void
→ request에 속성 값이 제거될 때 실행
attributeReplaced (ServletRequestAttributeEvent e) : void
→ request에 속성 값이 변경될 때 실행