Servlet – 事件和监听器
“事件”一词是指某事的发生。当对象的状态发生变化时会发生事件。当这些异常发生时,我们可以进行一些关键的操作,比如收集总登录用户数和当前登录用户数,部署项目时建立数据库表,建立数据库连接对象等等。 javax.servlet 和 javax.servlet.http 包包含许多 Event 类和 Listener 接口。
GUI 应用程序中侦听器的主要函数是集中来自特定 GUI 组件的事件,使用侦听器函数处理它,并向 GUI 应用程序提供响应。以下技术在 GUI 应用程序中称为事件处理或事件委托模型。
活动类别
Servlet 事件分为两类:高级和低级。
- Servlet 上下文级别(应用程序级别)事件:此事件涉及设备 servlet 上下文对象范围内的资源或状态。
- 会话级事件:它涉及与来自单个用户会话的一系列请求相关联的资源或状态;换句话说,它与 HTTP 会话对象相关联。
这两个级别中的每一个都有两种类型的事件:
- 生命周期的变化
- 属性变化
对于四个事件类别中的每一个,我们都可以定义一个或多个事件侦听器类。单个侦听器类可以监视多个事件类别。从 javax.servlet 包或 javax.servlet.http 包实现一个或多个接口是创建场合类的常用方法。
事件侦听器接口
Listener Interface | Description |
---|---|
javax.servlet.AsyncListener | Listener that will be alerted if an asynchronous action started on a ServletRequest to which the listener was attached has completed, timed out, or failed. |
javax.servlet.ServletContextListener | Interface for receiving ServletContext lifecycle change notification events. |
javax.servlet.ServletContextAttributeListener | Interface for receiving ServletContext attribute changes notification events. |
javax.servlet.ServletRequestListener | Interface for receiving notifications about requests entering and exiting a web application’s scope. |
javax.servlet.ServletRequestAttributeListener | Interface for receiving ServletRequest attribute changes notification events. |
javax.servlet.http.HttpSessionListener | Interface for receiving HttpSession lifecycle changes notification events. |
javax.servlet.http.HttpSessionBindingListener | When an object is tied to or freed from a session, it is alerted by javax.servlet.http.HttpSessionBindingListener. |
javax.servlet.http.HttpSessionAttributeListener | Interface for receiving HttpSession attribute change notification events. |
javax.servlet.http.HttpSessionActivationListener | Objects that are connected to a javax.servlet.http.HttpSessionActivationListener |
使用监听器的步骤
如果我们想在我们的网络应用程序中使用监听器监听器,我们必须遵循以下步骤:
第 1 步:准备好 Listener 类。
取一个用户自定义类,必须是Listener接口实现类。例如,考虑公共类 Listener 由 MyListener{……} 实现
第 2 步:在 web.xml 文件中,配置 Listener 类。
必须在 web.xml 文件中使用以下 XML 标记来配置 Listener 类:
……
Name of the Listener class
……
除了 HttpSessionBindingListener 和 HttpSessionActivationListener 之外,所有的 Listener 都需要上述的 listener 配置。
事件监听器和相关类的方法
1) ServletContextListeners 和 ServletContextEvent 类的方法
以下方法由 ServletContextListener 定义: Methods Descriptionvoid contextInitialized(ServletContextEvent sce) This function is used to inform the listener that the servlet context has been formed and that the application is now ready to handle requests. void contextDestroyed(ServletContextEvent sce) This function is used to alert the listener that the program is about to be terminated.
在服务器上部署 Web 应用程序时,将通知 ServletContextEvent。它包括下面显示的技术,您的听众可能会调用它:
ServletContext getServletContext():此方法检索已创建或将要删除的 servlet 上下文对象,您可以从中获取所需的任何信息。
2) ServletContextAttributeListener 和 ServletContextAttributeEvent 类的方法
ServletContextAttributeListener 指定以下方法: Methods Descriptionvoid attributeAdded(ServletContextAttributeEvent scae): It’s used to inform the listener that the servlet context has been updated with an attribute. void attributeRemoved(ServletContextAttributeEvent scae): It’s used to inform the listener that an attribute from the servlet context has been deleted. void attributeReplaced(ServletContextAttributeEvent scae) It’s used to inform the listener when an attribute in the servlet context has been replaced.
事件类 ServletContextAttributeEvent 用于通知 Web 应用程序的 servlet 上下文属性的更改。它包括下面列出的技术,您的听众可以使用这些技术:
- String getName()以字符串形式返回添加、删除或替换的属性名称。
- Object getValue()是一种用于检索已添加、删除或替换的属性值的方法。在替换属性的情况下,此方法返回以前的值,而不是新值。
3) HttpSessionListeners 和 HttpSessionEvent 类的方法
HttpSessionListener 指定以下方法: Methods Descriptionvoid sessionCreated(HttpSessionEvent hse) It’s used to inform the listener that a session has been established. void sessionDestroyed(HttpSessionEvent hse): It’s used to let the listener know that a session has been terminated.
当会话对象被修改时,会通知 HttpSessionEvent。它包括下面显示的技术,您的听众可能会调用它:
HttpSession getSession() :该函数用于获取生成或删除的会话对象。
4) HttpSessionAttributeListener 和 HttpSessionBindingEvent 类的方法
HttpSessionAttributeListener 指定以下方法: Methods Descriptionvoid attributeAdded(HttpSessionBindingEvent hsbe) It informs the listener that a new attribute has been introduced to the session. void attributeRemoved(HttpSessionBindingEvent hsbe) It’s used to inform the listener when a session attribute has been deleted. void attributeReplaced(HttpSessionBindingEvent hsbe) It’s used to inform the listener when an attribute in the session has been replaced.
当对象实现 HttpSessionBindingListener 被绑定或从会话中释放时,HttpSessionBindingEvent 被传递到该对象,或者当任何属性在会话中绑定、取消绑定或替换时,传递到已在部署描述符中设置的 HttpSessionAttributeListener。它包括下面列出的技术,您的听众可以使用这些技术:
- String getName():以字符串形式返回被添加、删除或替换的属性名称。
- Object getValue():是一种用于检索已添加、删除或替换的属性值的方法。在替换属性的情况下,此方法返回以前的值,而不是新值。
- HttpSession getSession():该方法用于获取属性发生变化的会话对象。
例子
为了演示 servlet 侦听器的实际操作,让我们创建一个基本的 Web 应用程序。在 Eclipse 中,我们将构建一个名为 ServletListenerExample 的动态 Web 项目,项目结构将如下所示。
上下文初始化参数和侦听器设置将在 web.xml 中定义。用于数据库连接的类是 DatabaseManager。该对象将作为属性添加到 servlet 上下文中。我将处理 MyServlet 中的会话、特征和其他内容。我们将使用 AppContextListener 读取 servlet 上下文初始化参数并使用它们创建 DatabaseManager 对象,然后我们将其设置为 ServletContext 对象的属性。 ServletContextAttributeListener 是一个简单的实现,用于在添加、删除或替换 servlet 上下文中的属性时记录事件。 HttpSessionListener 是一个简单的实现,用于在会话创建或销毁时记录事件。 ServletRequestListener 是在请求初始化和销毁时记录 servletRequest IP 地址。
web.xml
XML
ServletListenersGfg
DBUSER
root
DBPWD
root
DBURL
jdbc:mysql://localhost/mysql_db
com.geeksforgeeks.listener.AppContextListener
com.geeksforgeeks.listener.AppContextAttributeListener
com.geeksforgeeks.listener.MySessionListener
com.geeksforgeeks.listener.MyServletRequestListener
Java
package com.geeksforgeeks.db;
import java.sql.Connection;
public class DatabaseManager {
private String dbURL;
private String user;
private String password;
private Connection con;
public DatabaseManager(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
}
}
Java
package com.geeksforgeeks.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()
+ "}");
}
}
Java
package com.geeksforgeeks.listener;
import com.geeksforgeeks.db.*;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@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
DatabaseManager dbManager
= new DatabaseManager(url, u, p);
ctx.setAttribute("DBManager", dbManager);
System.out.println(
"Database connection initialized for Application.");
}
public void contextDestroyed(
ServletContextEvent servletContextEvent)
{
ServletContext ctx
= servletContextEvent.getServletContext();
DatabaseManager dbManager
= (DatabaseManager)ctx.getAttribute(
"DBManager");
dbManager.closeConnection();
System.out.println(
"Database connection closed for Application.");
}
}
Java
package com.geeksforgeeks.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());
}
}
Java
package com.geeksforgeeks.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());
}
}
Java
package com.geeksforgeeks.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", "GeeksForGeeks");
String user = (String)ctx.getAttribute("User");
ctx.removeAttribute("User");
HttpSession session = request.getSession();
session.invalidate();
PrintWriter out = response.getWriter();
out.write("Hi " + user);
}
}
数据库管理器。Java
Java
package com.geeksforgeeks.db;
import java.sql.Connection;
public class DatabaseManager {
private String dbURL;
private String user;
private String password;
private Connection con;
public DatabaseManager(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
}
}
应用上下文属性监听器。Java
Java
package com.geeksforgeeks.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()
+ "}");
}
}
应用上下文监听器。Java
Java
package com.geeksforgeeks.listener;
import com.geeksforgeeks.db.*;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@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
DatabaseManager dbManager
= new DatabaseManager(url, u, p);
ctx.setAttribute("DBManager", dbManager);
System.out.println(
"Database connection initialized for Application.");
}
public void contextDestroyed(
ServletContextEvent servletContextEvent)
{
ServletContext ctx
= servletContextEvent.getServletContext();
DatabaseManager dbManager
= (DatabaseManager)ctx.getAttribute(
"DBManager");
dbManager.closeConnection();
System.out.println(
"Database connection closed for Application.");
}
}
MyServletRequestListener。Java
Java
package com.geeksforgeeks.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());
}
}
我的会话监听器。Java
Java
package com.geeksforgeeks.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());
}
}
我的Servlet。Java
Java
package com.geeksforgeeks.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", "GeeksForGeeks");
String user = (String)ctx.getAttribute("User");
ctx.removeAttribute("User");
HttpSession session = request.getSession();
session.invalidate();
PrintWriter out = response.getWriter();
out.write("Hi " + user);
}
}
输出:
当我们部署我们的应用程序并访问 MyServlet 时,服务器日志文件将包含以下日志。
在浏览器中,我们会看到类似这样的内容。