• Listener学习


    监听器Listener用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。

    分类:

        按监听的对象划分,可以分为

    • ServletContext对象监听器
    • HttpSession对象监听器
    • ServletRequest对象监听器

        按监听的事件划分

    • 对象自身的创建和销毁的监听器
    • 对象中属性的创建和消除监听器
    • session中的某个对象的状态变化监听器

    ====================================================================

    整个web应用,即为ServletContext对象(对应jsp的隐式对象application)

    对Context的监听分为生命周期的监听,和Context上Attribute变化的监听两种。

    编写 ContextListener

    ContextListener 实现接口ServletContextListener有两个方法

    对应当前web应用的销毁:

    public void contextDestroyed(ServletContextEvent arg0)

    对应当前web应用的初始化:

    public void contextInitialized(ServletContextEvent arg0)

    代码:

    package listener;
     
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
     
    public class ContextListener implements ServletContextListener {
     
        @Override
        public void contextDestroyed(ServletContextEvent arg0) {
            System.out.println("web 应用销毁  ");
        }
     
        @Override
        public void contextInitialized(ServletContextEvent arg0) {
            System.out.println("web 应用初始化 "); 
        }
    }

    配置web.xml

    配置ContextListener

    <listener>
        <listener-class>listener.ContextListener</listener-class>
    </listener>

    测试

    在启动tomcat以及当前web应用重载的时候可以观察到
    web应用的自动重载需要如下前提:
    1. 配置: server.xml中对应的<context配置 的属性 @reloadable="true"
    2. 某个servlet 发生了变化,导致这个web应用自动重启

    --------------------------------------------------------------------------------------------

    编写ContextAttributeListener

    ContextAttributeListener 实现接口ServletContextAttributeListener,
    分别提供如下方法:

    监听属性的增加:

    public void attributeAdded(ServletContextAttributeEvent e)

    监听属性的移除 :

    public void attributeRemoved(ServletContextAttributeEvent e)

    监听属性的替换:

    public void attributeReplaced(ServletContextAttributeEvent e)

    代码:

    package listener;
     
    import javax.servlet.ServletContextAttributeEvent;
    import javax.servlet.ServletContextAttributeListener;
     
    public class ContextAttributeListener implements ServletContextAttributeListener {
     
        @Override
        public void attributeAdded(ServletContextAttributeEvent e) {
            System.out.println("增加属性 ");
            System.out.println("属性是" + e.getName());
            System.out.println("值是" + e.getValue());
     
        }
     
        @Override
        public void attributeRemoved(ServletContextAttributeEvent e) {
            // TODO Auto-generated method stub
            System.out.println("移除属性 ");
        }
     
        @Override
        public void attributeReplaced(ServletContextAttributeEvent e) {
            // TODO Auto-generated method stub
            System.out.println("替换属性");
        }
     
    }

    配置web.xml

    配置ContextAttributeListener

    <listener>
        <listener-class>listener.ContextAttributeListener</listener-class>
    </listener>

    testContext.jsp

    故意造成Context属性的增加,替换和移除

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     
    <%
        application.setAttribute("test", 1);
        application.setAttribute("test", 2);
        application.removeAttribute("test");
    %>

    测试

     访问页面进行测试
    http://127.0.0.1/testContext.jsp

    ====================================================================

    对Session的监听分生命周期的监听,和Session上Attribute变化的监听两种。

    编写 SessionListener

    SessionListener 实现了接口 HttpSessionListener

    session创建的时候执行:
    sessionCreated()

    session销毁的时候执行:

    sessionDestroyed()

    代码:

    package listener;
     
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
     
    public class SessionListener implements HttpSessionListener {
     
        @Override
        public void sessionCreated(HttpSessionEvent e) {
     
            System.out.println("监听到 session 创建, sessionid 是: " + e.getSession().getId());
        }
     
        @Override
        public void sessionDestroyed(HttpSessionEvent e) {
     
            System.out.println("监听到 session 销毁, sessionid 是: " + e.getSession().getId());
        }
    }

    配置web.xml

    配置SessionListener

    <listener>
        <listener-class>listener.SessionListener</listener-class>
    </listener>
    测试 
    随意访问任意页面
    如果是第一次访问,都会触发session创建,后续访问不会触发session的创建
    关闭浏览器,再访问,也会触发session的创建。 但是有的浏览器,即便是关闭了,下一次打开,也会发送以前sessionid到服务器,这样服务器就不会创建新的session。 
    session的销毁不易观察到,一般说来服务器会设置session存活时间为30分钟。所以需要等待才能观察到销毁。
    : 在重启tomcat测试之前, 要删除D: omcatworkCatalinalocalhost\_SESSIONS.ser 这个文件。 这个文件是tomcat存放以前的session的,为了观察到创建session的活动,需要tomcat重启之前把以前的session都清除掉,才能观察到新创建session的活动
     

    -------------------------------------------------------------------------------------------- 

    编写 SessionAttributeListener

    SessionAttributeListener 实现接口 HttpSessionAttributeListener

    当在session中增加属性时触发:

    attributeAdded()

    当在session中移除属性时触发:

    attributeRemoved()

    当替换session中的属性时触发:

    attributeReplaced()

    代码:

    package listener;
     
    import javax.servlet.http.HttpSessionAttributeListener;
    import javax.servlet.http.HttpSessionBindingEvent;
     
    public class SessionAttributeListener implements HttpSessionAttributeListener {
     
        @Override
        public void attributeAdded(HttpSessionBindingEvent e) {
     
            System.out.println("session 增加属性 ");
            System.out.println("属性是" + e.getName());
            System.out.println("值是" + e.getValue());
     
        }
     
        @Override
        public void attributeRemoved(HttpSessionBindingEvent e) {
            // TODO Auto-generated method stub
            System.out.println("session 移除属性 ");
     
        }
     
        @Override
        public void attributeReplaced(HttpSessionBindingEvent e) {
            // TODO Auto-generated method stub
            System.out.println("session 替换属性 ");
     
        }
    }

    配置web.xml

    配置 listener.SessionAttributeListener

    <listener>
        <listener-class>listener.SessionAttributeListener</listener-class>
    </listener>  

    testSession.jsp

    在testSession.jsp中,设置session属性 test=1,test=2, 接着删除

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     
    <%
        session.setAttribute("test", 1);
        session.setAttribute("test", 2);
        session.removeAttribute("test");
    %>

    测试

    访问页面

    http://127.0.0.1/testSession.jsp

    观察结果

    ====================================================================

    对Request的监听分生命周期的监听,和Request上Attribute变化的监听两部分。

    编写 RequestListener
    RequestListener 实现接口 ServletRequestListener和ServletRequestAttributeListener

    当新创建了一个Request的时候触发:

    只要访问了服务端的资源,就会创建一个Request,无论是jsp,servlet还是html

    requestInitialized()

    当本次请求结束的时候触发:

    requestDestroyed()

    当有新增属性时触发:

    attributeAdded()

    当有替换属性时触发:

    attributeReplaced()

    当有移除属性时触发:

    attributeRemoved()

    代码:

    package listener;
     
    import javax.servlet.ServletRequestAttributeEvent;
    import javax.servlet.ServletRequestAttributeListener;
    import javax.servlet.ServletRequestEvent;
    import javax.servlet.ServletRequestListener;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
     
    public class RequestListener implements ServletRequestListener, ServletRequestAttributeListener {
     
        @Override
        public void requestDestroyed(ServletRequestEvent arg0) {
            System.out.println("销毁了一个Request ");
        }
     
        @Override
        public void requestInitialized(ServletRequestEvent arg0) {
            System.out.println("创建了一个Request ");
        }
     
        @Override
        public void attributeAdded(ServletRequestAttributeEvent e) {
            System.out.println("request 增加属性 ");
            System.out.println("属性是" + e.getName());
            System.out.println("值是" + e.getValue());
        }
     
        @Override
        public void attributeRemoved(ServletRequestAttributeEvent arg0) {
            System.out.println("request 移除属性 ");
             
        }
     
        @Override
        public void attributeReplaced(ServletRequestAttributeEvent arg0) {
            System.out.println("request 替换属性 ");
             
        }
    }

    配置web.xml

    <listener>
        <listener-class>listener.RequestListener</listener-class>
    </listener>  

    testRequest.jsp

    测试页面,先在request中设置test,然后替换,最后移出掉test

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     
    <%
        request.setAttribute("test", 1);
        request.setAttribute("test", 2);
        request.removeAttribute("test");
    %>

    测试

    访问页面

    http://127.0.0.1/testRequest.jsp

    观察测试结果

    ====================================================================

    案例: 借助SESSION监听器统计当前在线人数

    HTTP协议是短链接的,所以无法在服务端根据建立了多少连接来统计当前有多少人在线。 不过可以通过统计session有多少来估计在线人数。一旦一个用户访问服务器,就会创建一个session. 如果该用户持续访问,那么该session会持续有效。如果经历了30分钟,该用户也没有做任何操作,就表示该用户“下线” 了,其对应的session也会被销毁。所以可以通过统计有多少session被保留来估计当前在线人数。

    编写 OnlineNumberListener

    OnlineNumberListener 实现接口HttpSessionListener

    当创建一个session的时候,就把数字+1,并且放在application里。

    ServletContext application = e.getSession().getServletContext();

    这就是jsp里的application

    注: 第一次从application里取数据的时候,是空的,要设置为0,当销毁一个session的时候,把这个数字-1。

    package listener;
     
    import javax.servlet.ServletContext;
     
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
     
    public class OnlineNumberListener implements HttpSessionListener {
     
        @Override
        public void sessionCreated(HttpSessionEvent e) {
     
            ServletContext application = e.getSession().getServletContext();
     
            Integer online_number = (Integer) application.getAttribute("online_number");
     
            if (null == online_number)
                online_number = 0;
            online_number++;
            application.setAttribute("online_number", online_number);
             
            System.out.println("新增一位在线用户");
        }
     
        @Override
        public void sessionDestroyed(HttpSessionEvent e) {
     
            ServletContext application = e.getSession().getServletContext();
     
            Integer online_number = (Integer) application.getAttribute("online_number");
     
            if(null==online_number){
                online_number = 0;
            }
            else
                online_number--;
            application.setAttribute("online_number", online_number);
            System.out.println("一位用户离线");
        }
    }

    配置web.xml

    配置 listener.OnlineNumberListener

    <listener>
        <listener-class>listener.OnlineNumberListener</listener-class>
    </listener>

    checkOnlineNumber.jsp

    通过EL表达式,直接获取application中的值

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" isELIgnored="false"%>
      
     当前 在线人数 : ${online_number}

     测试

    访问网页

     http://127.0.0.1/checkOnlineNumber.jsp

     注: 在重启tomcat测试之前, 要删除D: omcatworkCatalinalocalhost\_SESSIONS.ser 这个文件。 这个文件是tomcat存放以前的session的,为了观察到创建session的活动,需要tomcat重启之前把以前的session都清除掉,才能观察到新创建session的活动

  • 相关阅读:
    JavaScript中{}+{}
    网站性能优化
    C++是如何从代码到游戏的?
    C++是如何从代码到游戏的?
    【力扣】至少是其他数字两倍的最大数 中速题解
    代码编辑器选择Atom还是VScode?
    TIOBE 4 月榜单:少儿编程语言 Scratch 进入 TOP 20
    熟悉一下oncontextmenu事件的知识
    input属性type为file打开文件资源管理器时,如何限制多次选取或只能一次选取的行为
    HTML5的拖放事件
  • 原文地址:https://www.cnblogs.com/churujianghudezai/p/11836246.html
Copyright © 2020-2023  润新知