1. 监听器概述

1.1. 什么是监听器

做过Swing或者AWT图像界面Java程序开发的话,应该对Listener与Event非常熟悉。Swing或者AWT中通过Listener与Event来处理事件,如鼠标事件、键盘事件等。先实现一个Listener接口,然后通过addListener()方法把Listener绑定到某个控件上,单机按钮时就会调用Listener的相应方法,并传回一个Event对象。

Java Web程序也一样,使用Listener与Event完成相应事件的处理。使用Listener不需要关注该类事件是怎样触发的或者怎么调用相应的Listener,只要记住该类事件触发时一定会调用相应的Listener。遵循Servlet规范的服务器完成了相应的工作。开发者只要在Listener里编写相关代码就OK了。

1.2. 八大监听器

Java Web一共提供了八个监听器供使用,分别用于监听Request、Session和ServletContext等的创建与销毁、属性变化。这八个监听器分别如下:

  • ServletRequestListner

Method Summary

void

requestDestroyed(ServletRequestEvent sre) 
The request is about to go out of scope of the web application.

void

requestInitialized(ServletRequestEvent sre) 
The request is about to come into scope of the web application.

  • ServletRequestAttributeListener

Method Summary

void

attributeAdded(ServletRequestAttributeEvent srae) 
Notification that a new attribute was added to the servlet request.

void

attributeRemoved(ServletRequestAttributeEvent srae) 
Notification that an existing attribute has been removed from the servlet request.

void

attributeReplaced(ServletRequestAttributeEvent srae) 
Notification that an attribute was replaced on the servlet request.

  • HttpSessionListener

Method Summary

void

sessionCreated(HttpSessionEvent se) 
Notification that a session was created.

void

sessionDestroyed(HttpSessionEvent se) 
Notification that a session is about to be invalidated.

  • HttpSessionAttributeListener

Method Summary

void

attributeAdded(HttpSessionBindingEvent se) 
Notification that an attribute has been added to a session.

void

attributeRemoved(HttpSessionBindingEvent se) 
Notification that an attribute has been removed from a session.

void

attributeReplaced(HttpSessionBindingEvent se) 
Notification that an attribute has been replaced in a session.

  • ServletContextListener

Method Summary

void

contextDestroyed(ServletContextEvent sce) 
Notification that the servlet context is about to be shut down.

void

contextInitialized(ServletContextEvent sce) 
Notification that the web application initialization process is starting.

  • ServletContextAttributeListener

Method Summary

void

attributeAdded(ServletContextAttributeEvent scab) 
Notification that a new attribute was added to the servlet context.

void

attributeRemoved(ServletContextAttributeEvent scab) 
Notification that an existing attribute has been removed from the servlet context.

void

attributeReplaced(ServletContextAttributeEvent scab) 
Notification that an attribute on the servlet context has been replaced.

  • HttpSessionBindingListener

Method Summary

void

valueBound(HttpSessionBindingEvent event) 
Notifies the object that it is being bound to a session and identifies the session.

void

valueUnbound(HttpSessionBindingEvent event) 
Notifies the object that it is being unbound from a session and identifies the session.

  • HttpSessionActivationListener

Method Summary

void

sessionDidActivate(HttpSessionEvent se) 
Notification that the session has just been activated.

void

sessionWillPassivate(HttpSessionEvent se) 
Notification that the session is about to be passivated.

1.3. 自定义监听器

如果要自定义一个监听器的话,需要如下几步:

  • 创建一个自定义监听器类,并实现上述八个监听器中的一个或多个。
  • 配置Web工程的web.xml文件,格式如下:
<listener>
<listener-class>自定义监听器的完整路径</listener-class>
</listener>

2. 创建销毁监听器

2.1. ServletRequestListener

ServletRequestListener用于监听Request的创建与销毁。用户每次请求Request都会执行requestInitialized()方法,Request处理完毕自动销毁前执行requestDestroyed()方法。

需要注意的是如果一个页面内含有多个图片等元素,则请求一次页面可能会触发多次Request事件。

2.2. HttpSessionListener

HttpSessionListener用于监听Session的创建与销毁。创建Session时执行sessionCreated()方法,销毁Session或Session超时时执行sessionDestroyed()方法。该Listener可用于收集在线者信息。

2.3. ServletContextListener

ServletContextListener用于监听ServletContext的创建与销毁。服务器启动或者部署Web应用程序时执行contextInitialized()方法,服务器关闭或关闭Web应用程序时执行contextDestroyed()方法。该Listener可用于启动时获取web.xml文件中配置的初始化参数。

2.4. 监听Request、Session及ServletContext

编写一个监听器,分别实现ServletRequestListener、HttpSessionListener和ServletContextListener,并重写上述三个接口提供的方法。

  • 编写一个自定义监听器。
public class ListenerTest implements ServletRequestListener, HttpSessionListener, ServletContextListener {
/**
* requestInitialized()用于监听Request对象的创建.
* * 该方法在Request对象创建后被调用.
*/
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("客户端向服务器端发送了一次请求......");
}
/**
* requestDestroyed()用于监听Request对象的销毁.
* * 该方法在Request对象销毁前被调用.
*/
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("客户端的请求结束了......");
}
/**
* sessionCreated()用于监听Session对象的创建.
* * 该方法在Session对象创建后被调用.
*/
public void sessionCreated(HttpSessionEvent se) {
System.out.println("新创建了一个session......");
}
/**
* sessionDestroyed()用于监听Session对象的销毁.
* * 该方法在Session对象销毁前被调用.
*/
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("销毁了一个session......");
}
/**
* contextInitialized()用于监听ServletContext对象的创建.
* * 该方法在ServletContext对象创建后被调用.
*/
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Web应用即将启动......");
}
/**
* contextDestroyed()用于监听ServletContext对象的销毁.
* * 该方法在ServletContext对象销毁前被调用.
*/
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Web应用即将关闭......");
}
}
  • 在web.xml文件中配置自定义监听器。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>app.java.listener.ListenerTest</listener-class>
</listener>
</web-app>

3. 属性操作监听器

3.1. ServletRequestAttributeListener

ServletRequestAttributeListener用于监听Request对象添加、更新和移除属性。Request添加属性时执行requestAdded()方法,Request对象更新属性时执行requestReplaced()方法,Request对象移除属性时执行requestRemoved()方法。

3.2. HttpSessionAttributeListener

HttpSessionAttributeListener用于监听Session对象添加、更新和移除属性。Session添加属性时执行sessionAdded()方法,Session对象更新属性时执行sessionReplaced()方法,Session对象移除属性时执行sessionRemoved()方法。

3.3. ServletContextAttributeListener

ServletContextAttributeListener用于监听ServletContext对象添加、更新和移除属性。ServletContext添加属性时执行contextAdded()方法,ServletContext对象更新属性时执行contextReplaced()方法,Session对象移除属性时执行contextRemoved()方法。

3.4. 监听ServletRequestAttributeListener、HttpSessionAttributeListener及ServletContextAttributeListener

编写一个监听器,分别实现ServletRequestAttributeListener、HttpSessionAttributeListener和ServletContextAttributeListener,并重写上述三个接口提供的方法。

  • 编写一个自定义监听器。
public class AttributeListenerTest implements ServletRequestAttributeListener, HttpSessionAttributeListener, ServletContextAttributeListener {
/**
* attributeAdded(ServletRequestAttributeEvent srae)用于监听Request对象添加属性.
* * 该方法在Request对象添加属性后被调用.
*/
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("成功向Request对象添加了一个属性......");
}
/**
* attributeRemoved(ServletRequestAttributeEvent srae)用于监听Request对象删除属性.
* * 该方法在Request对象删除属性前被调用.
*/
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("成功向Request对象删除了一个属性......");
}
/**
* attributeReplaced(ServletRequestAttributeEvent srae)用于监听Request对象更新属性.
* * 该方法在Request对象更新属性前被调用.
*/
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.println("成功向Request对象更新了一个属性......");
}
/**
* attributeAdded(HttpSessionBindingEvent se)用于监听Session对象添加属性.
* * 该方法在Session对象添加属性后被调用.
*/
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("成功向Session对象添加了一个属性......");
}
/**
* attributeRemoved(HttpSessionBindingEvent se)用于监听Session对象删除属性.
* * 该方法在Session对象删除属性前被调用.
*/
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("成功向Session对象删除了一个属性......");
}
/**
* attributeReplaced(HttpSessionBindingEvent se)用于监听Session对象更新属性.
* * 该方法在Session对象更新属性前被调用.
*/
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("成功向Session对象更新了一个属性......");
}
/**
* attributeAdded(ServletContextAttributeEvent scab)用于监听ServletContex对象添加属性.
* * 该方法在ServletContex对象添加属性后被调用.
*/
public void attributeAdded(ServletContextAttributeEvent scab) {
System.out.println("成功向ServletContex对象添加了一个属性......");
}
/**
* attributeRemoved(ServletContextAttributeEvent scab)用于监听ServletContex对象删除属性.
* * 该方法在ServletContex对象删除属性前被调用.
*/
public void attributeRemoved(ServletContextAttributeEvent scab) {
System.out.println("成功向ServletContex对象删除了一个属性......");
}
/**
* attributeReplaced(ServletContextAttributeEvent scab)用于监听ServletContex对象更新属性.
* * 该方法在ServletContex对象更新属性前被调用.
*/
public void attributeReplaced(ServletContextAttributeEvent scab) {
System.out.println("成功向ServletContex对象更新了一个属性......");
}
}
  • 在web.xml文件中配置自定义监听器。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>app.java.listener.AttributeListenerTest</listener-class>
</listener>
</web-app>

4. Session绑定监听器

4.1. JavaBean感知监听

HttpSessionBindingListener用于当JavaBean对象被放到Session里时执行valueBound()方法,当JavaBean对象从Session移除时执行valueUnBound()方法。JavaBean必须实现该Listener接口。

  • 创建一个JavaBean,实现HttpSessionBindingListener接口。
public class User implements HttpSessionBindingListener {
private String name;
private int age;
private String job;
public User(String name, int age, String job) {
this.name = name;
this.age = age;
this.job = job;
}
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;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", job=" + job + "]";
}
/**
* valueBound()将该JavaBean对象放置到Session时被调用.
*/
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("该JavaBean被添加到session中......");
}
/**
* valueUnbound()将该JavaBean对象从Session移除时被调用.
*/
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("该JavaBean从session中被移除......");
}
}
  • 创建一个Servlet用于将JavaBean对象放置到Session和从Session移除。
public class BeanServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("user", new User("zhangwuji", 18, "jiaozhu"));
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.removeAttribute("user");
}
}

使用HttpSessionBindingListener监听器时,不需要配置web.xml文件。

5. Session钝化与活化

5.1. Session序列化

所谓Session序列化就是指当Tomcat服务器关闭时Session会被保存到本地硬盘中,当Tomcat服务器启动时Session会从本地硬盘读取到内存中的过程。

  • 创建一个Servlet用于向Session中存放数据内容。
public class SetSessionServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("name", "zhangwuji");
System.out.println("成功向session存储了数据......");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 创建一个Servlet用于从Session中读取存放的数据内容。
public class GetSessionServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String name = (String) session.getAttribute("name");
System.out.println("session中存储的数据内容为: "+name+"......");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 发布Web工程到Tomcat服务器,并启动Tomcat服务器。访问向Session存储数据的Servlet。
  • 关闭Tomcat服务器,查看${CATALINA_HOME}\work\Catalina\localhost\Web工程名目录。
  • 重新启动Tomcat服务器,访问从Session读取存储数据的Servlet。

当Tomcat服务器被重新启动读取Session内容之后,序列化到本地硬盘中的Session文件会自动销毁。

如果想要关闭Session的序列化,可以修改Tomcat安装目录中conf目录的context.xml文件。具体内容如下:

<Manager pathname=""/>

5.2. Session钝化与活化

当Session长时间不被使用时(没有超时),将Session里的内容保存到本地硬盘中,这个过程叫做钝化。当Session重新被使用时,将保存到本地硬盘中的Session里的内容重新读取,这个过程叫做活化。

  • 创建一个Servlet用于向Session中存放数据内容。
public class SetSessionServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute("name", "zhangwuji");
System.out.println("成功向session存储了数据......");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
  • 创建一个Servlet用于从Session中读取存放的数据内容。
public class GetSessionServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String name = (String) session.getAttribute("name");
System.out.println("session中存储的数据内容为: "+name+"......");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
  • 修改Tomcat安装目录/conf目录/ Catalina目录/ localhost目录中,创建一个名为Web工程名的xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- maxIdleSwap:指定多长时间后Session会被钝化.(单位为分钟) -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1" >
<!--
directory:指定钝化文件的保存目录.
钝化文件保存路径:${CATALINA_HOME}\work\Catalina\localhost\Web工程名\${sessionid}.session
-->
<Store className="org.apache.catalina.session.FileStore" directory="mysession" />
</Manager>
</Context>

钝化文件在重新被使用时,不会自动销毁。

6. 监听器案例

6.1. 统计在线人数

利用Java Web的监听器技术,实现在线人数统计的案例,具体实现步骤如下:

  • 创建一个监听器,实现ServletContextListener接口,用于初始化在线人数为0。
public class OnLineCountServletContextListener implements
ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
// 通过 事件对象,获得事件源ServletContext
ServletContext servletContext = sce.getServletContext();
// 只会执行一次
servletContext.setAttribute("onlinecount", 0);
}
public void contextDestroyed(ServletContextEvent sce) {}
}
  • 创建一个监听器,实现HttpSessionListener接口,用于统计在线人数。
public class OnLineCountHttpSessionListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent se) {
// 获得ServletContext
ServletContext servletContext = se.getSession().getServletContext();
// 获得原来在线人数
int onlinecount = (Integer) servletContext.getAttribute("onlinecount");
System.out.println(se.getSession().getId() + "在线了...");
servletContext.setAttribute("onlinecount", onlinecount + 1);
}
public void sessionDestroyed(HttpSessionEvent se) {
// 获得ServletContext
ServletContext servletContext = se.getSession().getServletContext();
// 获得原来在线人数
int onlinecount = (Integer) servletContext.getAttribute("onlinecount");
System.out.println(se.getSession().getId() + "离线了...");
servletContext.setAttribute("onlinecount", onlinecount - 1);
}
}
  • 配置Web工程的web.xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>app.java.demo.OnLineCountServletContextListener</listener-class>
</listener>
<listener>
<listener-class>app.java.demo.OnLineCountHttpSessionListener</listener-class>
</listener>
</web-app>
  • 创建一个JSP页面用于显示在线人数。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>在线人数统计案例</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<h1>在线人数:${applicationScope.onlinecount }</h1>
</body>
</html>
  • 发布Web工程到Tomcat服务器,并启动Tomcat服务器。访问对应的JSP页面查看结果。

JavaWeb Listener的更多相关文章

  1. JavaWeb——Listener

    一.基本概念 JavaWeb里面的listener是通过观察者设计模式进行实现的.对于观察者模式,这里不做过多介绍,大概讲一下什么意思. 观察者模式又叫发布订阅模式或者监听器模式.在该模式中有两个角色 ...

  2. JavaWeb Listener之HttpSessionBindListener

    HttpSessionBindListener        监听把自身这个对象绑定到HttpSession对象上.解绑 绑定到HttpSession对象上,其实就是调用session的setAttr ...

  3. JavaWeb:Listener和Filter

    本文内容: Listener Filter 首发日期:2018-07-15 Listener 监听器Listener负责监听事件的发生.我们能在事件发生后执行一些自定义的操作,这就是监听器的意义. 监 ...

  4. JavaWeb Listener之HttpSessionActivationListener ,session钝化、活化

    HttpSessionActivationListener    监听HttpSession对象的活化.钝化 钝化:将HttpSession对象从内存中转移至硬盘,存储为.session文件. 活化: ...

  5. JavaWeb—监听器Listener

    1.简介 Listener是Servlet的监听器,Servlet 监听器用于监听一些重要事件的发生,监听器对象在事情发生前.发生后可以做一些必要的处理. JavaWeb里面的listener是通过观 ...

  6. filter和listener的生命周期

    filter(过滤器)和listener(监听器)的生命周期 老实说 生命周期要是说成作用的时间范围我会理解的更好 filter package com.javaweb.filter; import ...

  7. 监听域对象创建和销毁的Listener

    1.什么是Servlet监听器? 先来看看什么是监听器.监听器是专门用于对其它对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时立即采取相应的行动.Servlet监听器是S ...

  8. 域对象中属性变更及感知session绑定的事件监听器

    域对象中属性的变更的时间监听器就是用来监听ServletContext,HttpSession,HttpServletRequest这三个对象中的属性变更信息事件的监听器.这三个监听器接口分别是Ser ...

  9. JavaWEB 通过Listener理解域对象生命周期

    利用 ServletRequestListener.HttpSessionListener 以及 ServletContextListener 可以把request,session,以及Applica ...

随机推荐

  1. C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西付给另一个类对象,而不是付给引用地址)

    from:https://blog.csdn.net/poxiaohai2011/article/details/27555951 //C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西 ...

  2. 【转】Linux下mysql操作

    本文转自:http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/10/18/2216279.html 1.linux下启动mysql的命令:my ...

  3. cxGrid 显示行号及行号列列名

    cxGrid默认不显示行号,但是可以通过cxGrid1DBTableView1CustomDrawIndicatorCell事件来重绘行号 选中cxGrid1DBTableView1,在OnCusto ...

  4. 170122、Netty 长连接服务

    推送服务 还记得一年半前,做的一个项目需要用到 Android 推送服务.和 iOS 不同,Android 生态中没有统一的推送服务.Google 虽然有 Google Cloud Messaging ...

  5. ES正在弱化type这个概念

    百度Elasticsearch-产品描述-介绍-百度云 https://cloud.baidu.com/doc/BES/System.html#.E5.9F.BA.E6.9C.AC.E6.A6.82. ...

  6. gitlab 阿里邮箱配置

    gitlab 阿里邮箱配置 # gitlab_rails['smtp_user_name'] = "smtp user"# gitlab_rails['smtp_password' ...

  7. jmeter断言之BeanShell断言

    1.添加BeanShell断言,在Script下面写断言脚本,常用的BeanShell脚本如下: if(!SampleResult.getResponseCode().equals("200 ...

  8. 字符串 (string)与字节数组(byte[])之间的转换

    string str = "abc" //字符串转成编码为GB2312的byte[] byte[] pData =System.Text.Encoding.GetEncoding( ...

  9. python collection 和 heapq 模块使用说明

    一 :集合库collection python 拥有一些内置的数据类型,collections模块提供啦几个额外的数据类型: 1,namedtuple   生成可以使用名字来访问元素内容的tuple子 ...

  10. springMvc获取特殊值

    1.获取数组