웹사이트 검색

ServletContextListener 서블릿 리스너 예제


ServletContextListener는 우리가 가지고 있는 많은 Servlet Listener 중 하나입니다. 이것은 Java Web Application 시리즈의 다섯 번째 기사입니다. 이전 네 개의 기사도 확인하고 싶을 수 있습니다.

  1. 자바 웹 애플리케이션
  2. 자바의 서블릿
  3. 서블릿 세션 관리
  4. 서블릿 필터

서블릿 리스너

서블릿 리스너가 있는 이유는 무엇입니까? 서블릿 리스너 인터페이스 및 이벤트 객체 서블릿 리스너 구성 서블릿 리스너 예 ServletContextListener ServletContextAttributeListener HttpSessionListener 서블릿 요청 리스너 서블릿 리스너가 있는 이유는 무엇입니까?

우리는 ServletContext를 사용하여 다른 모든 서블릿이 액세스할 수 있는 애플리케이션 범위를 가진 속성을 생성할 수 있지만 배포 설명자(web.xml)에서만 문자열로 ServletContext 초기 매개변수를 초기화할 수 있음을 알고 있습니다. 애플리케이션이 데이터베이스 지향적이고 데이터베이스 연결을 위해 ServletContext에 속성을 설정하려는 경우 어떻게 됩니까? 애플리케이션에 단일 진입점(사용자 로그인)이 있는 경우 첫 번째 서블릿 요청에서 이를 수행할 수 있지만 진입점이 여러 개인 경우 모든 곳에서 이를 수행하면 많은 코드 중복이 발생합니다. 또한 데이터베이스가 다운되었거나 제대로 구성되지 않은 경우 첫 번째 클라이언트 요청이 서버에 올 때까지 알 수 없습니다. 이러한 시나리오를 처리하기 위해 서블릿 API는 이벤트를 수신하고 특정 작업을 수행하도록 구현 및 구성할 수 있는 수신기 인터페이스를 제공합니다. 이벤트는 무언가 발생하는 것입니다. 웹 애플리케이션 세계에서 이벤트는 애플리케이션의 초기화, 애플리케이션 파괴, 클라이언트의 요청, 세션 생성/파괴, 세션의 속성 수정 등이 될 수 있습니다. Servlet API는 우리가 구현할 수 있는 다양한 유형의 리스너 인터페이스를 제공합니다. 특정 이벤트가 발생할 때 무언가를 처리하도록 web.xml에서 구성합니다. 예를 들어, 위의 시나리오에서 우리는 애플리케이션 시작 이벤트에 대한 리스너를 생성하여 컨텍스트 초기화 매개변수를 읽고 데이터베이스 연결을 생성하고 다른 리소스에서 사용할 수 있도록 컨텍스트 속성으로 설정할 수 있습니다.8. ### 서블릿 리스너 인터페이스 및 이벤트 객체

Servlet API는 다양한 유형의 이벤트에 대해 다양한 종류의 리스너를 제공합니다. 리스너 인터페이스는 유사한 이벤트 그룹과 함께 작동하는 메서드를 선언합니다. 예를 들어 컨텍스트의 시작 및 종료 이벤트를 수신하는 ServletContext Listener가 있습니다. 리스너 인터페이스의 모든 메소드는 Event 객체를 입력으로 사용합니다. 이벤트 객체는 리스너에게 특정 객체를 제공하는 래퍼 역할을 합니다. Servlet API는 다음과 같은 이벤트 객체를 제공합니다.

  1. javax.servlet.AsyncEvent - ServletRequest에서 시작된 비동기 작업(ServletRequest#startAsync 또는 ServletRequest#startAsync(ServletRequest, ServletResponse)에 대한 호출을 통해)이 완료, 시간 초과 또는 오류 생성 시 발생하는 이벤트입니다.
  2. javax.servlet.http.HttpSessionBindingEvent - 이 유형의 이벤트는 세션에서 결합 또는 결합 해제될 때 HttpSessionBindingListener를 구현하는 객체로 전송되거나 속성이 있을 때 web.xml에 구성된 HttpSessionAttributeListener로 전송됩니다. 바인딩, 바인딩 해제 또는 세션에서 대체됩니다. 세션은 HttpSession.setAttribute를 호출하여 객체를 결합하고 HttpSession.removeAttribute를 호출하여 객체를 결합 해제합니다. 개체가 세션에서 제거될 때 정리 작업에 이 이벤트를 사용할 수 있습니다.
  3. javax.servlet.http.HttpSessionEvent - 웹 애플리케이션 내의 세션 변경에 대한 이벤트 알림을 나타내는 클래스입니다.
  4. javax.servlet.ServletContextAttributeEvent - 웹 애플리케이션의 ServletContext 속성 변경에 대한 알림을 위한 이벤트 클래스
  5. javax.servlet.ServletContextEvent - 웹 애플리케이션의 서블릿 컨텍스트 변경에 대한 알림을 위한 이벤트 클래스입니다.
  6. javax.servlet.ServletRequestEvent - 이러한 종류의 이벤트는 ServletRequest에 대한 수명 주기 이벤트를 나타냅니다. 이벤트 소스는 이 웹 애플리케이션의 ServletContext입니다.
  7. javax.servlet.ServletRequestAttributeEvent - 애플리케이션에서 서블릿 요청의 속성 변경 알림을 위한 이벤트 클래스입니다.

Servlet API는 다음과 같은 Listener 인터페이스를 제공합니다.

javax.servlet.AsyncListener - 리스너가 추가된 ServletRequest에서 시작된 비동기 작업이 완료, 시간 초과 또는 오류가 발생한 경우 알림을 받을 리스너입니다.\n\n\njavax.servlet.ServletContextListener - ServletContext 수명 주기 변경에 대한 알림 이벤트를 수신하기 위한 인터페이스입니다.\n\n\njavax.servlet.ServletContextAttributeListener - ServletContext 속성 변경에 대한 알림 이벤트를 수신하기 위한 인터페이스입니다.\n\n\njavax.servlet.ServletRequestListener - 웹 애플리케이션의 범위에 들어오고 나가는 요청에 대한 알림 이벤트를 수신하기 위한 인터페이스입니다.\n\n\njavax.servlet.ServletRequestAttributeListener - ServletRequest 속성 변경에 대한 알림 이벤트를 수신하기 위한 인터페이스입니다.\n\n\njavax.servlet.http.HttpSessionListener - HttpSession 수명 주기 변경에 대한 알림 이벤트를 수신하기 위한 인터페이스입니다.\n\n\njavax.servlet.http.HttpSessionBindingListener - 객체가 세션에 바인딩되거나 바인딩 해제될 때 알림을 받도록 합니다.\n\n\njavax.servlet.http.HttpSessionAttributeListener - HttpSession 속성 변경에 대한 알림 이벤트를 수신하기 위한 인터페이스입니다.\n\n\njavax.servlet.http.HttpSessionActivationListener - 세션에 바인딩된 개체는 세션이 비활성화되고 해당 세션이 활성화됨을 알리는 컨테이너 이벤트를 수신할 수 있습니다. HttpSessionActivationListener를 구현하는 세션에 바인딩된 모든 특성을 알리려면 VM 간에 세션을 마이그레이션하거나 세션을 유지하는 컨테이너가 필요합니다.\n\n\n서블릿 리스너 구성

주석을 사용하여 클래스를 Listener로 선언할 수 있지만 클래스는 하나 이상의 Listener 인터페이스를 구현해야 합니다. web.xml에서 리스너를 다음과 같이 정의할 수 있습니다.

<listener>
    <listener-class>
    com.journaldev.listener.AppContextListener
    </listener-class>
</listener>

서블릿 리스너 예

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ServletListenerExample</display-name>
  
  <context-param>
    <param-name>DBUSER</param-name>
    <param-value>pankaj</param-value>
  </context-param>
  <context-param>
    <param-name>DBPWD</param-name>
    <param-value>password</param-value>
  </context-param>
  <context-param>
    <param-name>DBURL</param-name>
    <param-value>jdbc:mysql://localhost/mysql_db</param-value>
  </context-param>
  
  <listener>
    <listener-class>com.journaldev.listener.AppContextListener</listener-class>
  </listener>
  <listener>
    <listener-class>com.journaldev.listener.AppContextAttributeListener</listener-class>
  </listener>
  <listener>
    <listener-class>com.journaldev.listener.MySessionListener</listener-class>
  </listener>
  <listener>
    <listener-class>com.journaldev.listener.MyServletRequestListener</listener-class>
  </listener>
</web-app>

DBConnectionManager: 이것은 데이터베이스 연결을 위한 클래스입니다. 단순화를 위해 실제 데이터베이스 연결을 위한 코드는 제공하지 않습니다. 이 객체를 서블릿 컨텍스트의 속성으로 설정합니다.

package com.journaldev.db;

import java.sql.Connection;

public class DBConnectionManager {

	private String dbURL;
	private String user;
	private String password;
	private Connection con;
	
	public DBConnectionManager(String url, String u, String p){
		this.dbURL=url;
		this.user=u;
		this.password=p;
		//create db connection now
		
	}
	
	public Connection getConnection(){
		return this.con;
	}
	
	public void closeConnection(){
		//close DB connection here
	}
}

MyServlet: 세션, 속성 등으로 작업할 간단한 서블릿 클래스입니다.

package com.journaldev.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			ServletContext ctx = request.getServletContext();
			ctx.setAttribute("User", "Pankaj");
			String user = (String) ctx.getAttribute("User");
			ctx.removeAttribute("User");
			
			HttpSession session = request.getSession();
			session.invalidate();
			
			PrintWriter out = response.getWriter();
			out.write("Hi "+user);
	}

}

이제 리스너 클래스를 구현할 것입니다. 일반적으로 사용되는 리스너인 ServletContextListener, ServletContextAttributeListener, ServletRequestListener 및 HttpSessionListener.27에 대한 샘플 리스너 클래스를 제공합니다. ## ServletContextListener

서블릿 컨텍스트 초기화 매개변수를 읽어 DBConnectionManager 객체를 생성하고 ServletContext 객체의 속성으로 설정합니다.

package com.journaldev.listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import com.journaldev.db.DBConnectionManager;

@WebListener
public class AppContextListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent servletContextEvent) {
    	ServletContext ctx = servletContextEvent.getServletContext();
    	
    	String url = ctx.getInitParameter("DBURL");
    	String u = ctx.getInitParameter("DBUSER");
    	String p = ctx.getInitParameter("DBPWD");
    	
    	//create database connection from init parameters and set it to context
    	DBConnectionManager dbManager = new DBConnectionManager(url, u, p);
    	ctx.setAttribute("DBManager", dbManager);
    	System.out.println("Database connection initialized for Application.");
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    	ServletContext ctx = servletContextEvent.getServletContext();
    	DBConnectionManager dbManager = (DBConnectionManager) ctx.getAttribute("DBManager");
    	dbManager.closeConnection();
    	System.out.println("Database connection closed for Application.");
    	
    }
	
}

ServletContextAttributeListener

서블릿 컨텍스트에서 속성이 추가, 제거 또는 대체될 때 이벤트를 기록하는 간단한 구현입니다.

package com.journaldev.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppContextAttributeListener implements ServletContextAttributeListener {

    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
    	System.out.println("ServletContext attribute added::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
    }

    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
    	System.out.println("ServletContext attribute replaced::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
    }

    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
    	System.out.println("ServletContext attribute removed::{"+servletContextAttributeEvent.getName()+","+servletContextAttributeEvent.getValue()+"}");
    }
	
}

HttpSessionListener

세션이 생성되거나 소멸될 때 이벤트를 기록하는 간단한 구현입니다.

package com.journaldev.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class MySessionListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent sessionEvent) {
    	System.out.println("Session Created:: ID="+sessionEvent.getSession().getId());
    }

    public void sessionDestroyed(HttpSessionEvent sessionEvent) {
    	System.out.println("Session Destroyed:: ID="+sessionEvent.getSession().getId());
    }
	
}

서블릿 요청 리스너

요청이 초기화 및 소멸될 때 ServletRequest IP 주소를 기록하기 위한 ServletRequestListener 인터페이스의 간단한 구현입니다.

package com.journaldev.listener;

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyServletRequestListener implements ServletRequestListener {

    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
    	ServletRequest servletRequest = servletRequestEvent.getServletRequest();
    	System.out.println("ServletRequest destroyed. Remote IP="+servletRequest.getRemoteAddr());
    }

    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
    	ServletRequest servletRequest = servletRequestEvent.getServletRequest();
    	System.out.println("ServletRequest initialized. Remote IP="+servletRequest.getRemoteAddr());
    }
	
}

이제 애플리케이션을 배포하고 URL https://localhost:8080/ServletListenerExample/MyServlet을 사용하여 브라우저에서 MyServlet에 액세스하면 서버 로그 파일에 다음 로그가 표시됩니다.

ServletContext attribute added::{DBManager,com.journaldev.db.DBConnectionManager@4def3d1b}
Database connection initialized for Application.
ServletContext attribute added::{org.apache.jasper.compiler.TldLocationsCache,org.apache.jasper.compiler.TldLocationsCache@1594df96}

ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1%0
ServletContext attribute added::{User,Pankaj}
ServletContext attribute removed::{User,Pankaj}
Session Created:: ID=8805E7AE4CCCF98AFD60142A6B300CD6
Session Destroyed:: ID=8805E7AE4CCCF98AFD60142A6B300CD6
ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1%0


ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1%0
ServletContext attribute added::{User,Pankaj}
ServletContext attribute removed::{User,Pankaj}
Session Created:: ID=88A7A1388AB96F611840886012A4475F
Session Destroyed:: ID=88A7A1388AB96F611840886012A4475F
ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1%0


Database connection closed for Application.

로그의 순서와 실행 순서를 확인하십시오. 애플리케이션을 종료하거나 컨테이너를 종료하면 마지막 로그가 나타납니다.

이것이 서블릿의 리스너에 대한 전부입니다. 다음으로 쿠키와 몇 가지 일반적인 서블릿 예제를 살펴보겠습니다. 아래 링크에서 프로젝트를 다운로드하고 가지고 놀면서 자세히 알아볼 수 있습니다.

서블릿 리스너 예제 프로젝트 다운로드

Servlet의 쿠키에 대한 시리즈의 다음 기사를 확인하십시오.