您的位置:首页 > Web前端 > JavaScript

Servlet JSP Tutorial -- 1.5 ServletContextListener Servlet Listener Example

2018-01-10 09:25 447 查看
ServletContextListener是我们拥有的许多SerServletContextListener是我们拥有的许多Servlet监听器之一。 这是本系列中的第五篇文章,你可能还想查看前面的四篇文章。

Java Web Application

Servlets in Java

Servlet Session Management

Servlet Filter

Servlet Listener

在本教程中,我们将研究 servlet 监听器;servlet 监听器的好处;我们可以对监听器,servlet API 监听器接口和 Event 对象执行的一些常见任务。 最后,我们将创建一个简单的 Web 项目来展示常用的 ServletContext、Session和ServletRequest 的 Listener实现的例子。

Why do we have Servlet Listener?

Servlet Listener Interfaces and Event Objects

Servlet Listener Configuration

Servlet Listener Example

ServletContextListener

ServletContextAttributeListener

HttpSessionListener

ServletRequestListener

Why do we have Servlet Listener?

我们能知道,使用 ServletContext,我么可以创建一个具有其他 servlet 可以访问的应用程序范围的属性。单丝我们可以只在部署描述符(web.xml)中将 ServletContext 初始化参数初始化为 String。如果我们的应用是面向数据库的,而且我们希望在 ServletContext for Database Connection 中设置一个属性。如果你的应用有一个入口点(用户登陆),那么那你可以在第一个 servlet 请求中执行此操作,但是如果我们有多个入口点,那么在任何地方进行操作都会导致大量的代码冗余。另外,如果数据库关闭着或者配置不正确,我们直到第一个客户端情趣到服务器才会知道。为了处理这些场景,servlet API 提供了 Listener 接口,我么可以实现和配置这些接口来监听事件并执行某些操作。

事件是一些事情的发生,在 Web 应用程序中,事件可以是应用的初始化;应用的销毁;来自客户端的请求;创建、销毁会话;会话中的属性修改等。

Servlet API 提供不同类型的 Listener 接口,我们可以实现并在 web.xml 中配置来处理特定时间发生时的事情。栗如,在上面的场景中,我们可以为应用程序启动事件创建一个 listener 来读取上下文的 init 参数,并创建一个数据库连接将其设置为上下文属性供其他资源使用。

Servlet Listener Interfaces and Event Objects

Servlet API 提供不同类型的 Listener 接口,我们可以实现并在 web.xml 中配置来处理特定时间发生时的事情。栗如,在上面的场景中,我们可以为应用程序启动事件创建一个 listener 来读取上下文的 init 参数,并创建一个数据库连接将其设置为上下文属性供其他资源使用。

Servlet API 提供了以下事件对象:

javax.servlet.AsyncEvent – 在 ServletRequest(通过调用 ServletRequest#startAsync 或 ServletRequest#startAsync(ServletRequest, ServletResponse))启动异步操作完成、超时或产生错误时出发的事件。

javax.servlet.http.HttpSessionBindingEvent

– 这种类型的事件被发送到实现 HttpSessionBindingListener 的对象,当它绑定或从一个会话中解除绑定时,或者当任何属性被绑定,解绑定或在会话中被替换时,被绑定到 web.xml 中配置的HttpSessionAttributeListener。

会话通过对 HttpSession.setAttribute 的调用来绑定对象,并通过调用HttpSession.removeAttribute 来解除绑定对象。

当对象从会话中删除时,我们可以使用此事件进行清理活动。

javax.servlet.http.HttpSessionEvent – 这是表示 Web 应用程序中会话更改的事件通知的类。

javax.servlet.ServletContextAttributeEvent –事件类,用于通知有关Web 应用程序的 ServletContext 属性的更改。

javax.servlet.ServletContextEvent – 这是有关 Web 应用程序的 servlet上下文更改通知的事件类。

javax.servlet.ServletRequestEvent – 这种事件表示 ServletRequest 的生命周期事件。事件的来源是这个 Web 应用程序的 ServletContext。

javax.servlet.ServletRequestAttributeEvent – 这是应用程序中 servlet 请求属性更改通知的事件类。

Servlet API 提供了以下 Listener 接口:

javax.servlet.AsyncListener – 如果在已经添加了监听器的ServletRequest上发起的异步操作已经完成,超时或导致错误,将会通知的监听器。

javax.servlet.ServletContextListener – 用于接收有关 ServletContext 生命周期更改的通知事件的接口。

javax.servlet.ServletContextAttributeListener – 用于接收有关 ServletContext 属性更改的通知事件的接口。

javax.servlet.ServletRequestListener – 用于接收有关进入和退出 Web 应用程序范围的请求的通知事件的接口。

javax.servlet.ServletRequestAttributeListener – 用于接收有关 ServletRequest 属性更改的通知事件的接口。

javax.servlet.http.HttpSessionListener – 用于接收有关 HttpSession 生命周期更改的通知事件的接口。

javax.servlet.http.HttpSessionBindingListener – 使对象在与会话绑定或解除时得到通知。

javax.servlet.http.HttpSessionAttributeListener – 用于接收有关 HttpSession 属性更改的通知事件的接口。

javax.servlet.http.HttpSessionActivationListener – 绑定到会话的对象可以监听容器事件,通知他们会话将被钝化,并且会话将被激活。在 VM 之间迁移会话或持久会话的容器需要通知绑定到实现 HttpSessionActivationListener 的会话的所有属性。

Servlet Listener Configuration

我们可以使用 @WebListener 注解来声明一个类为 Listener,但是该类应该实现一个或多个 Listener 接口。

我们可以在 web.xml 中定义 listener:

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


Servlet Listener Example

让我们创建一个简单的 Web 应用程序来查看 servlet 监听器的运行情况。我们将在 IDEA 中创建动态 Web 项目 ServletListenerExample 这些项目结构将如下图所示。

web.xml:在部署描述符中,我将定义一些上下文 init params 和 listener 配置。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmln 4000
s.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<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:这是数据库连接的类,为简单起见,我不提供实际的数据库连接的代码。我们将这个对象设置为 servlet 上下文的属性。

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:一个简单的servlet类,我将使用会话,属性等。

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。

ServletContextListener

我们将读取 servlet 上下文初始化参数来创建 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

在添加,删除或在 servlet 上下文中替换属性时记录事件的简单实现。

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());
}

}


ServletRequestListener

ServletRequestListener 接口的简单实现,用于在请求被初始化和销毁时记录ServletRequest 的IP地址。

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 http:// localhost:8080/Servlet在浏览器中访问 Servlet 时,我们将在服务器日志文件中看到以下日志。

[2018-01-09 08:16:04,880] Artifact ServletListenerExample:war exploded: Artifact is being deployed, please wait...
ServletContext attribute added::{DBManager,com.journaldev.db.DBConnectionManager@7c7cc49}
Database connection initialized for Application.
[2018-01-09 08:16:05,412] Artifact ServletListenerExample:war exploded: Artifact is deployed successfully
[2018-01-09 08:16:05,427] Artifact ServletListenerExample:war exploded: Deploy took 532 milliseconds
ServletRequest initialized. Remote IP=127.0.0.1
ServletContext attribute added::{org.apache.jasper.runtime.JspApplicationContextImpl,org.apache.jasper.runtime.JspApplicationContextImpl@65d3d261}
ServletContext attribute added::{org.apache.jasper.compiler.ELInterpreter,org.apache.jasper.compiler.ELInterpreterFactory$DefaultELInterpreter@406bf107}
Session Created:: ID=73ABD9F56DB2D223802BCF19F58B852C
ServletRequest destroyed. Remote IP=127.0.0.1
ServletRequest initialized. Remote IP=127.0.0.1
Session Created:: ID=5C935319A51415BA11ED380640BE407C
ServletRequest destroyed. Remote IP=127.0.0.1
ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1
Session Created:: ID=1E2535CAD0D7FF1BF715B0EEC94902A3
ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1
09-Jan-2018 20:16:14.564 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [D:\Program Files\Apache Software Foundation\Tomcat 8.5\webapps\manager]
09-Jan-2018 20:16:14.595 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [D:\Program Files\Apache Software Foundation\Tomcat 8.5\webapps\manager] has finished in [31] ms
ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1
ServletContext attribute added::{User,Pankaj}
ServletContext attribute removed::{User,Pankaj}
Session Destroyed:: ID=1E2535CAD0D7FF1BF715B0EEC94902A3
ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1
ServletRequest initialized. Remote IP=0:0:0:0:0:0:0:1
ServletContext attribute added::{User,Pankaj}
ServletContext attribute removed::{User,Pankaj}
Session Created:: ID=15921657BFD8234A0779E9DA3F07037F
Session Destroyed:: ID=15921657BFD8234A0779E9DA3F07037F
ServletRequest destroyed. Remote IP=0:0:0:0:0:0:0:1


这就是 servlet 监听器的全部内容。我们接下来会看到cookie和一些常见的servlet实例。

下一篇文章Cookies in Servlet.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  servlet filter java