Java ---Listener监听器

在我们的web容器中,一直不断的触发着各种事件,例如:web应用启动和关闭,request请求到达和结束等。但是这些事件通常对于开发者来说是透明的,我们可以根据这些接口开发符合我们自身需求的功能。在web中常见的的几个监听事件如下:

  • ServletContextListener:用于监听web应用的启动和关闭
  • ServletContextAttributeListener:用于监听在application范围内的数据的变动
  • ServletRequestListener:用于监听用户请求的细节
  • ServletRequestAttributeListener:用于监听request范围内的数据的变动
  • HttpSessionListener:用于监听某次会话的开始和结束
  • HttpSessionAttributeListener:用于监听session范围内的属性数据的变动

一、使用ServletContextListener监听web应用的启动和关闭
我们想要实现一个自定义的Listener,需要两个步骤,第一个是根据自己的需求继承相应的上述的监听事件的接口,并实现其中的相应的方法。第二个步骤就是,在web.xml中配置此Listener监听器的处理类或者使用注解配置。下面我们通过继承自ServletContextListener接口来实现对web应用的启动和关闭实时监控。

public class MyListener implements ServletContextListener {

    @Override//web应用启动时候触发此事件
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("web应用启动了。。。");
    }

    @Override//web应用关闭的时候触发事件
    public void contextDestroyed(ServletContextEvent sce) {

        System.out.println("web应用被关闭了。。。");
    }

}
<?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://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <listener>
        <listener-class>Test_packge.MyListener</listener-class>
    </listener>
</web-app>
1.png

二、使用ServletContextAttributeListener监听application范围内的属性变化
上面的代码可以让我们监听web应用的启动和关闭情况,下面我们可以通过实现ServletContextAttributeListener接口来完成对application范围内的属性数值改变情况进行监听。其中主要有以下三个方法:


    default void attributeAdded(ServletContextAttributeEvent scae) {
    }

    default void attributeRemoved(ServletContextAttributeEvent scae) {
    }

    default void attributeReplaced(ServletContextAttributeEvent scae) {
    }

这三个方法分别会在application范围内添加属性的时候,删除属性的时候,更新属性的时候触发。下面做一点演示:

public class MyListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {

        String name = scae.getName();
        Object value = scae.getValue();
        System.out.println("add: "+name+":"+value);
    }
    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {

        String name = scae.getName();
        Object value = scae.getValue();
        System.out.println("remove: "+name+":"+value);
    }
    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {

        String name = scae.getName();
        Object value = scae.getValue();
        System.out.println("replaced: "+name+":"+value);
    }
}
<%application.setAttribute("x","a");%>

<%application.removeAttribute("x","a");%>

上述代码中,我们调用了ServletContextAttributeEvent 对象的getName方法和getValue方法来获取当前的application属性的名和值。当然此对象还有另外一个方法就是用于获取servlecontext对象的。

三、使用ServletRequestListener监听用户请求的开始和结束
上述代码主要完成的是对web应用的启动和结束的状态进行监听,包括application范围内的属性值的改变的监听。下面我们看对用户请求进行监听的接口ServletRequestListener,它主要有两个方法:

    default void requestDestroyed(ServletRequestEvent sre) {
    }

    default void requestInitialized(ServletRequestEvent sre) {
    }

这两个方法分别会在请求的到达和请求的结束时触发,ServletRequestEvent 中定义的方法可以返回当前请求的对象request和web应用的ServletContext对象。通过继承接口ServletRequestAttributeListener可以实现监听request范围内的属性的变更,其内部方法和上述的ServletContextAttributeListener 类似,不演示了。

四、使用HttpSessionListener监听会话的开始和结束
HttpSessionListener监听器用于监听每个用户创建会话和关闭会话的动作,有两个方法:

    default void sessionCreated(HttpSessionEvent se) {
    }

    default void sessionDestroyed(HttpSessionEvent se) {
    }

一个是用于监听会话开始,一个是用于监听会话的结束。HttpSessionEvent 类可以返回一HttpSession对象,该对象指向当前会话,可以从中获取会话创建的时间,属性值,sessionId,ServletContext对象等。通过他我们可以直接的监视具体用户的各个操作。下面我们通过一个例子:显示当前所有在线的用户

public class MyListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent se) {

        ServletContext app = se.getSession().getServletContext();
        //如果是新一次会话
        if(se.getSession().isNew()){
            Map<String,String> map = (Map<String,String>)app.getAttribute("online");
            if(map==null){
                //如果这是第一次会话,创建一个用于记录在线人数的map集合
                map = new Hashtable<String, String>();
            }
            //此处的用户名实际上是可以获取的,此处为了演示方便,默认walekr
            map.put(se.getSession().getId(),"walker");
            app.setAttribute("online",map);
        }
    }
    public void sessionDestroyed(HttpSessionEvent se) {

        ServletContext app = se.getSession().getServletContext();
        Map<String,String> map = (Map<String,String>)app.getAttribute("online");
        if(map!=null) {
            map.remove(se.getSession().getId());
        }
        app.setAttribute("online",map);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title></title>
  </head>
  <body>
      <%
        Map<String,String> map = (Map<String,String>)application.getAttribute("online");
        for(String key : map.keySet()){
      %>
      <p><%=key%>:<%=map.get(key)%></p>
    <%}%>
  </body>
</html>
2.png

做一点解释,当用户使用浏览器访问服务器时候,会为此用户创建session对象,我们监听创建session动作,在application范围内创建map映射集合用于记录sessionId和用户名,sessionId是web容器为我们自动创建的不会重复的序列。我们可以打开多个浏览器模拟多用户访问,可以看到结果如上图所示,输出了所有与在线的用户sessionId和用户名。需要注意一点的是,session对象在服务器端存在的是时间是有限的,也就是说如果某个用户长时间没有再次访问服务器更新session的话,服务器会自动清除该对象,也就导致用户可能需要重新登录。还有一点,每个客户端都会获取在服务器端的session对象,但是如果客户端关闭了,session并不会立即从服务器端清除,依然需要等到超时之后服务器删除该对象。具体的深入理解session,以后的文章会介绍,此处了解即可。

此外,HttpSessionAttributeListener可以用来监听session范围内的属性的变更,主要有如下几个方法:

    default void attributeAdded(HttpSessionBindingEvent se) {
    }

    default void attributeRemoved(HttpSessionBindingEvent se) {
    }

    default void attributeReplaced(HttpSessionBindingEvent se) {
    }

这三个方法和上述的几个监听属性的方法是类似的,此处不再赘述。

以上便是Listener监听器的基本内容,理解较为浅薄,望对大家有帮助!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,717评论 6 342
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,169评论 11 349
  • 转自:http://blog.csdn.net/jackfrued/article/details/4493113...
    王帅199207阅读 2,414评论 2 19
  • 央视曾经做过这样的采访:你幸福吗?我姓朱这样的回答也让这个调查变成了一个笑话。这样一想,世上除了最近变成表情包的尔...
    屁桃酱的文艺生活阅读 191评论 1 0