• JavaWeb Listener


    1. 监听器概述

    1.1. 什么是监听器

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

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

    1.2. 八大监听器

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

    • 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()方法,销毁SessionSession超时时执行sessionDestroyed()方法。该Listener可用于收集在线者信息。

    2.3. ServletContextListener

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

    2.4. 监听RequestSessionServletContext

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

    • 编写一个自定义监听器。
    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. 监听ServletRequestAttributeListenerHttpSessionAttributeListenerServletContextAttributeListener

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

    • 编写一个自定义监听器。
    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}workCatalinalocalhostWeb工程名目录。
    • 重新启动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}workCatalinalocalhostWeb工程名${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页面查看结果。
  • 相关阅读:
    Dp~Hrbust1426( 集训队的晚餐 )
    DP~数塔(hrbustoj1004)
    MyEclipse启动性能优化(----加快启动速度)
    很实用的php的缓存类文件示例
    PHP中9大缓存技术总结
    微信公众平台开发(76) 获取用户基本信息
    js中 onreadystatechange 和 onload的区别
    一个js文件导入js的函数
    PHP cURL实现模拟登录与采集使用方法详解教程
    Mysql清空表(truncate)与删除表中数据(delete)的区别
  • 原文地址:https://www.cnblogs.com/aaron911/p/7922185.html
Copyright © 2020-2023  润新知