ServletContextListener ist einer der vielen Servlet-Listener, die wir haben. Dies ist der fünfte Artikel in der Serie von Java Web-Anwendung, Sie möchten vielleicht auch die früheren vier Artikel überprüfen.
Servlet-Listener
In diesem Tutorial werden wir uns den Servlet-Listener ansehen, die Vorteile von Servlet-Listenern, einige gängige Aufgaben, die wir mit Listenern erledigen können, die Listener-Schnittstellen der Servlet-API und Ereignisobjekte. Am Ende werden wir ein einfaches Webprojekt erstellen, um ein Beispiel für die häufig verwendete Listener-Implementierung für ServletContext, Session und ServletRequest zu zeigen.
Wir wissen, dass wir mithilfe von ServletContext
ein Attribut mit Anwendungsbereich erstellen können, auf das alle anderen Servlets zugreifen können. Allerdings können wir ServletContext-Init-Parameter nur als String im Bereitstellungsdeskriptor (web.xml) initialisieren. Was ist jedoch, wenn unsere Anwendung datenbankorientiert ist und wir ein Attribut im ServletContext für die Datenbankverbindung setzen möchten? Wenn Ihre Anwendung einen einzigen Einstiegspunkt hat (Benutzeranmeldung), können Sie dies im ersten Servlet-Anforderungsaufruf tun. Wenn jedoch mehrere Einstiegspunkte vorhanden sind, führt dies zu viel Code-Redundanz, wenn wir es überall tun. Außerdem werden wir erst bei der ersten Client-Anforderung an den Server erfahren, wenn die Datenbank nicht verfügbar oder nicht ordnungsgemäß konfiguriert ist. Um mit diesen Szenarien umzugehen, bietet die Servlet-API Listener-Schnittstellen, die wir implementieren und konfigurieren können, um auf ein Ereignis zu hören und bestimmte Operationen durchzuführen. Ereignis ist das Eintreten von etwas. In der Welt von Webanwendungen kann ein Ereignis die Initialisierung der Anwendung, das Zerstören einer Anwendung, die Anforderung eines Clients, das Erstellen/Zerstören einer Sitzung, die Änderung von Attributen in einer Sitzung usw. sein. Die Servlet-API bietet verschiedene Arten von Listener-Schnittstellen, die wir implementieren und in der web.xml konfigurieren können, um etwas zu verarbeiten, wenn ein bestimmtes Ereignis eintritt. Zum Beispiel können wir in obigem Szenario einen Listener für das Starten der Anwendung erstellen, um Kontextinitialisierungsparameter zu lesen, eine Datenbankverbindung zu erstellen und sie als Kontextattribut für die Verwendung durch andere Ressourcen zu setzen.
Die Servlet-API bietet verschiedene Arten von Listenern für verschiedene Arten von Ereignissen. Listener-Schnittstellen deklarieren Methoden zum Arbeiten mit einer Gruppe ähnlicher Ereignisse. Zum Beispiel haben wir den ServletContext-Listener, um dem Start- und Beendigungsereignis des Kontexts zuzuhören. Jede Methode in der Listener-Schnittstelle nimmt ein Ereignisobjekt als Eingabe. Das Ereignisobjekt fungiert als Wrapper, um spezifische Objekte für die Zuhörer bereitzustellen. Die Servlet-API bietet folgende Ereignisobjekte an.
- javax.servlet.AsyncEvent – Ereignis, das ausgelöst wird, wenn die asynchrone Operation, die über einen Aufruf von ServletRequest#startAsync oder ServletRequest#startAsync(ServletRequest, ServletResponse) auf einer Servlet-Anforderung initiiert wurde, abgeschlossen, abgelaufen oder einen Fehler verursacht hat.
- javax.servlet.http.HttpSessionBindingEvent – Ereignisse dieses Typs werden entweder an ein Objekt gesendet, das HttpSessionBindingListener implementiert, wenn es an eine Sitzung gebunden oder von ihr gelöst wird, oder an einen HttpSessionAttributeListener, der in der web.xml konfiguriert wurde, wenn ein Attribut in einer Sitzung gebunden, gelöst oder ersetzt wird. Die Sitzung bindet das Objekt durch einen Aufruf von HttpSession.setAttribute und löst das Objekt durch einen Aufruf von HttpSession.removeAttribute. Wir können dieses Ereignis für Bereinigungsaktivitäten verwenden, wenn das Objekt aus der Sitzung entfernt wird.
- javax.servlet.http.HttpSessionEvent – Dies ist die Klasse, die Ereignisbenachrichtigungen für Änderungen an Sitzungen innerhalb einer Webanwendung darstellt.
- javax.servlet.ServletContextAttributeEvent – Ereignisklasse für Benachrichtigungen über Änderungen an den Attributen des Servlet-Kontexts einer Webanwendung.
- javax.servlet.ServletContextEvent – Dies ist die Ereignisklasse für Benachrichtigungen über Änderungen am Servletkontext einer Webanwendung.
- javax.servlet.ServletRequestEvent – Ereignisse dieser Art geben Lebenszyklusereignisse für ein ServletRequest an. Die Quelle des Ereignisses ist der Servletkontext dieser Webanwendung.
- javax.servlet.ServletRequestAttributeEvent – Dies ist die Ereignisklasse für Benachrichtigungen über Änderungen an den Attributen der Servletanforderung in einer Anwendung.
Die Servlet-API bietet folgende Listener-Schnittstellen.
-
javax.servlet.AsyncListener – Ein Listener, der benachrichtigt wird, wenn eine asynchrone Operation abgeschlossen ist, abgelaufen ist oder einen Fehler verursacht hat, die auf einem ServletRequest initiiert wurde, zu dem der Listener hinzugefügt wurde.
-
javax.servlet.ServletContextListener – Schnittstelle zum Empfangen von Benachrichtigungsevents über Änderungen am Lebenszyklus des Servletkontexts.
-
javax.servlet.ServletContextAttributeListener – Schnittstelle zum Empfangen von Benachrichtigungsevents über Änderungen an ServletContext-Attributen.
-
javax.servlet.ServletRequestListener – Schnittstelle zum Empfangen von Benachrichtigungsereignissen über Anfragen, die in den Scope einer Webanwendung ein- und aus dem Scope herauskommen.
-
javax.servlet.ServletRequestAttributeListener – Schnittstelle zum Empfangen von Benachrichtigungsereignissen über ServletRequest-Attributänderungen.
-
javax.servlet.http.HttpSessionListener – Schnittstelle zum Empfangen von Benachrichtigungsereignissen über Änderungen im HttpSession-Lebenszyklus.
-
javax.servlet.http.HttpSessionBindingListener – Veranlasst ein Objekt, benachrichtigt zu werden, wenn es an eine Sitzung gebunden oder von dieser gelöst wird.
-
javax.servlet.http.HttpSessionAttributeListener – Schnittstelle zum Empfangen von Benachrichtigungsereignissen über HttpSession-Attributänderungen.
-
javax.servlet.http.HttpSessionActivationListener – Objekte, die an eine Sitzung gebunden sind, können Containerereignisse abhören, die sie darüber informieren, dass Sitzungen passiviert und aktiviert werden. Ein Container, der Sitzungen zwischen VMs migriert oder Sitzungen beibehält, muss alle an Sitzungen gebundenen Attribute benachrichtigen, die HttpSessionActivationListener implementieren.
-
Servlet-Listener-Konfiguration
Wir können die @WebListener Annotation verwenden, um eine Klasse als Listener zu deklarieren, jedoch sollte die Klasse eine oder mehrere der Listener-Schnittstellen implementieren. Wir können den Listener in der web.xml wie folgt definieren:
<listener>
<listener-class>
com.journaldev.listener.AppContextListener
</listener-class>
</listener>
Lassen Sie uns eine einfache Webanwendung erstellen, um den Servlet-Listener in Aktion zu sehen. Wir werden ein dynamisches Webprojekt in Eclipse ServletListenerExample erstellen. Die Projektstruktur wird wie im folgenden Bild aussehen. web.xml: Im Bereitstellungsbeschreibungsdatei werde ich einige Kontext-Init-Parameter und Listener-Konfiguration definieren.
<?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: Dies ist die Klasse für die Datenbankverbindung. Aus Gründen der Einfachheit gebe ich keinen Code für die tatsächliche Datenbankverbindung an. Wir werden dieses Objekt als Attribut zum Servlet-Kontext setzen.
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;
// Jetzt Datenbankverbindung erstellen
}
public Connection getConnection(){
return this.con;
}
public void closeConnection(){
// Hier Datenbankverbindung schließen
}
}
MyServlet: Eine einfache Servlet-Klasse, in der ich mit Sitzungen, Attributen usw. arbeiten werde.
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);
}
}
Jetzt werden wir Listener-Klassen implementieren. Ich gebe Beispiellistener-Klassen für häufig verwendete Listener – ServletContextListener, ServletContextAttributeListener, ServletRequestListener und HttpSessionListener – an.27. ## ServletContextListener
Wir werden Servlet-Kontext-Init-Parameter lesen, um das DBConnectionManager-Objekt zu erstellen und es als Attribut zum ServletContext-Objekt zu setzen.
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");
// Datenbankverbindung aus den Init-Parametern erstellen und sie dem Kontext zuweisen
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.");
}
}
A simple implementation to log the event when attribute is added, removed or replaced in servlet context.
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()+"}");
}
}
A simple implementation to log the event when session is created or destroyed.
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());
}
}
A simple implementation of ServletRequestListener interface to log the ServletRequest IP address when request is initialized and destroyed.
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());
}
}
Wenn wir unsere Anwendung bereitstellen und MyServlet im Browser mit der URL https://localhost:8080/ServletListenerExample/MyServlet
aufrufen, sehen wir die folgenden Protokolle in der Server-Protokolldatei.
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.
Beachten Sie die Reihenfolge der Protokolle, die der Ausführungsreihenfolge entspricht. Das letzte Protokoll erscheint, wenn Sie die Anwendung oder den Container herunterfahren.
Das ist alles für den Listener im Servlet, als nächstes sehen wir uns Cookies und einige gängige Servlet-Beispiele an. Sie können das Projekt über den unten stehenden Link herunterladen und damit experimentieren, um mehr zu erfahren.
Download Servlet-Listener-Beispielprojekt
Werfen Sie einen Blick auf den nächsten Artikel in der Serie über Sitzungscookies in Servlet.
Source:
https://www.digitalocean.com/community/tutorials/servletcontextlistener-servlet-listener-example