监听器概述

在上一篇里介绍了过滤器Filter,而Listener是Servlet的另一个高级特性。Listener用于监听Java Web程序中的事件,例如创建,修改,删除Session,request,context等,并触发相应的事件。Listener主要用于对Session,request,context等进行监控,目前共有8种Listener,分别完成对不同事件的监听。

使用Listener不需要关注事件是怎样触发的或者怎么调用相应的Listener,只要记住该类事件触发时一定会调用相应的Listener。你只需要在Lisener里编写相关的代码就可以。

Servlet3.0以前需要在web.xml中配置,之后直接用@WebListener()注解即可。

<listener>
<listener-class>listener.TestListener</listener-class>
</listener>

监听对象的创建与销毁

HttpSessionListener,ServletContextListener,ServletRequestListener分别用来监控Session,context,request的创建于销毁。触发时机为:

  • HttpSessionListener:创建Session时执行sessionCreatedf方法,超时或者执行session.invalidate()时执行sessionDestroy方法。该Listener可用于收集在线者信息。
  • ServletContextListener:服务器启动或者热部署war包时执行contextInitialized方法。服务器关闭时执行contextDestroyed方法。该Listener可用于启动时获取web.xml里配置的初始化参数。
  • ServletRequest:用户每次请求时都会执行requestInitialized方法。request处理完毕自动销毁前执行requestDestroyed方法。

实例:因为java可以继承多个接口,所以用一个类继承这三个接口即可。

package listener; 

/**
* Created by kindleheart happily.
*/
import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; @WebListener
public class TestListener implements ServletContextListener, HttpSessionListener, ServletRequestListener {
public TestListener() {
} //加载context上下文时被调用
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
System.out.println("即将启动" + servletContext.getContextPath());
}
//销毁context上下文时被调用
public void contextDestroyed(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
System.out.println("即将关闭" + servletContext.getContextPath());
}
//创建Session时被调用
public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println("新创建一个Session,ID为:" + session.getId());
}
//销毁Session时被调用
public void sessionDestroyed(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println("销毁一个Session,ID为:" + session.getId());
}
//创建request时被调用
public void requestInitialized(ServletRequestEvent sre) {
//存储创建request时的时间
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
request.setAttribute("dateCrated", System.currentTimeMillis());
}
//销毁request时被调用
public void requestDestroyed(ServletRequestEvent sre) {
//计算该请求所需时间
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
long time = System.currentTimeMillis() - (Long)request.getAttribute("dateCrated");
System.out.println("请求处理结束,用时" + time + "毫秒");
} }

监听对象属性的变化

HttpSessionAttributeListener,ServletContextAttributeListener,ServletRequestAttributeListener分别用来监控Session,context,request的属性变化。在向监听对象添加,更新,移除属性时,会分别执行xxxAdded(),xxxReplaced(),xxxRemoved()方法,xxx分别代表Session,context,request。

/**
* Created by kindleheart happily.
*/
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*; @WebListener
public class SessionAttributeListenerTest implements HttpSessionAttributeListener {
public SessionAttributeListenerTest() { } public void attributeAdded(HttpSessionBindingEvent sbe) {
HttpSession session = sbe.getSession();
String name= sbe.getName(); //新添加的属性名
System.out.println("新建Session属性:" + name + ",值为:" + sbe.getValue());
} public void attributeRemoved(HttpSessionBindingEvent sbe) {
HttpSession session = sbe.getSession();
String name= sbe.getName(); //即将删除的属性名
System.out.println("删除Session属性:" + name + ",值为:" + sbe.getValue());
} public void attributeReplaced(HttpSessionBindingEvent sbe) {
HttpSession session = sbe.getSession();
String name= sbe.getName(); //发生修改的属性名
Object oldValue = sbe.getValue(); //原来的属性值
System.out.println("修改Session属性:" + name + ",旧值为:" + oldValue +"新值为:" + session.getAttribute(name));
}
}

监听Session内的对象

除了上面6种Listener,另外还有两种Listener用于监控Session内的对象,分别是HttpSessionBindingListener与HttpSessionActivationListener。他们触发的时机为:

  • HttpSessionBindingListener:当监听对象与Session绑定时执行valueBound方法,解绑时执行valueUnbound方法。
  • HttpSessionActivationListener:服务器关闭时,会将Session里的内容保存到硬盘上,这个过程称为钝化,执行sessionWillPassivate方法。服务器重新启动时,会将Session内容从硬盘上重新加载,会执行sessonDidActivate方法。

案例:把User对象与Session绑定时,就会执行相应的方法。

package model;
/**
* Created by kindleheart happily.
*/ import javax.servlet.http.*; public class User implements HttpSessionBindingListener, HttpSessionActivationListener {
private String name;
private int age; public User(String name, int age) {
this.name = name;
this.age = age;
} public User() {
} 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;
} @Override
public void sessionWillPassivate(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println(this + "已经成功从硬盘加载。SessionId:" + session.getId());
} @Override
public void sessionDidActivate(HttpSessionEvent se) {
HttpSession session = se.getSession();
System.out.println(this + "即将保存到硬盘。SessionId:" + session.getId());
} @Override
public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
String name = event.getName();
System.out.println(this + "被绑定到Session" + session.getId() + "的" + name + "属性上");
} @Override
public void valueUnbound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
String name = event.getName();
System.out.println(this + "被从Session" + session.getId() + "的" + name + "属性上移除");
}
}

应用:统计在线人数

用户第一次访问服务器时,服务器会创建一个Session,用户结束访问时会销毁这个Session,那么可以使用HttpSessionListener来统计在线人数。

package util;
/**
* Created by kindleheart happily.
*/ import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.HttpSessionBindingEvent; @WebListener()
public class OnlineNumListener implements HttpSessionListener {
private static int userNum = 0; public OnlineNumListener() {
} public static int getUserNum() {
return userNum;
} public void sessionCreated(HttpSessionEvent se) {
userNum++;
} public void sessionDestroyed(HttpSessionEvent se) {
userNum--;
}
}

 在主页显示在线人数:

<%@ page import="util.OnlineNumListener" %>
<%@page pageEncoding="utf-8" contentType="text/html; utf-8" language="java" isELIgnored="false" %>
<html>
<body>
<h2>我是主页</h2>
<%
int num = OnlineNumListener.getUserNum();
%>
<h3>在线人数为:</h3>><%=num%>
</body>
</html>

Java Web(五) 监听器Listener的更多相关文章

  1. 【java web】监听器listener

    一.简介 Java的监听器,也是系统级别的监听.监听器随web应用的启动而启动.Java的监听器在c/s模式里面经常用到,它会对特定的事件产生产生一个处理.监听在很多模式下用到,比如说观察者模式,就是 ...

  2. java web(五):java web三大组件之另外两个和八大监听器

    java的三大组件指Servlet.Filter.Listener.八大监听器指八个接口.前面介绍了Servlet,现在介绍一下Filter拦截器以及拦截地址的设置, Listener监听那些事件. ...

  3. java之Servlet监听器Listener

    常用应用场景:单点登录.统计在线人数 一.简介 (一)概述 1.Listener 用于监听 java web程序中的事件,例如创建.修改.删除Session.request.context等,并触发响 ...

  4. javaweb学习总结(四十五)——监听器(Listener)学习二

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

  5. JavaWeb学习 (二十五)————监听器(Listener)

    一.监听器介绍 1.1.监听器的概念

  6. Java Web(五) JSP详解(四大作用域九大内置对象等)

    前面讲解了Servlet,了解了Servlet的继承结构,生命周期等,并且在其中的ServletConfig和ServletContext对象有了一些比较详细的了解,但是我们会发现在Servlet中编 ...

  7. 学习java web中的listener

    web.xml里的顺序为:context-param->listener->filter->servlet 监听器是需要新建一个类,然后按监听的对象继承:ServletContext ...

  8. Java web学习总结

    javaweb学习总结(十四)——JSP原理 孤傲苍狼 2014-07-24 09:38 阅读:46603 评论:37     JavaWeb学习总结(十三)——使用Session防止表单重复提交 孤 ...

  9. Java Web学习总结(13)Listener监听器

    一,监听器介绍 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其实就是一个实现特定接口的普通java程序,这个程序 ...

随机推荐

  1. Activity回传值报错:Failure delivering result ResultInfo{who=null,request=7,result = 0,data=null}

    Activity  A   -----值------->  Activity  B   -----值----->  Activity  A     场景:当A跳转到B,再从B直接点击返回按 ...

  2. 百万并发中间件系统的内核设计看Java并发性能优化

    “ 这篇文章,给大家聊聊一个百万级并发的中间件系统的内核代码里的锁性能优化. 很多同学都对Java并发编程很感兴趣,学习了很多相关的技术和知识.比如volatile.Atomic.synchroniz ...

  3. CSS 控制鼠标在元素停留的样式

    以下资料来自网络,收藏学习总结用: 有时候需要改变鼠标样式,DIV 可以改成手型等,A也可以改成光标形式 巧合要用到鼠标样式效果,就顺便整理了下十五种CSS鼠标样式,小例子供大家使用啊.CSS鼠标样式 ...

  4. CC2 条理分明-----AACTP教你谈恋爱

      AACTP是一个神奇的地方,这里可以培养你的自信,培养你的沟通表达能力,培养你的领导管理能力:但是你不知道的是AACTP还可以培养你恋爱的本领.想知道是怎么回事吗?听我给你慢慢说来.我把恋爱分为三 ...

  5. python - argparse 模块学习

    python - argparse 模块学习 设置一个解析器 使用argparse的第一步就是创建一个解析器对象,并告诉它将会有些什么参数.那么当你的程序运行时,该解析器就可以用于处理命令行参数. 解 ...

  6. 日常英语---十四、Dolce & Gabbana cancels China show amid 'racist' ad controversy(adj.温柔的,prep.在其中)

    日常英语---十四.Dolce & Gabbana cancels China show amid 'racist' ad controversy(adj.温柔的,prep.在其中) 一.总结 ...

  7. 一个使用Jmeter做接口性能测试的实战案例

    1 安装并配置Jmeter Jmeter的安装不在这里阐述,安装步骤非常简单. 直接进入主题 1.1 数据库连接配置 由于测试过程需要调用数据库获取响应部署数据,因此需要先建立与数据库的连接. 如果不 ...

  8. Genome-wide gene-environment analyses of depression and reported lifetime traumatic experiences in UK Biobank

    Genome-wide gene-environment analyses of depression and reported lifetime traumatic experiences in U ...

  9. Hibernate多对多单向关联和双向关联 --Hibernate框架

    Hibernate关联关系中相对比较特殊的就是多对多关联,多对多关联与一对一关联和一对多关联不同,多对多关联需要另外一张映射表用于保存多对多映射信息.本例介绍多对多单向关联和双向关联.单向关联 :指具 ...

  10. Java类成员变量的默认值

    1.布尔型(boolean)变量默认值为false,byte.short.int.long为0,字符型为'\u0000'(空字符),浮点型(float double)为0.0,引用类型(String) ...