• 深入分析JavaWeb Item38 -- 监听器(Listener)高速学习


    一、监听器介绍

    1.1、监听器的概念

      这里写图片描写叙述

      监听器是一个专门用于对其它对象身上发生的事件或状态改变进行监听和对应处理的对象,当被监视的对象发生情况时,马上採取对应的行动。监听器事实上就是一个实现特定接口的普通java程序。这个程序专门用于监听还有一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法马上被执行。

    1.2、监听器案例——监听window窗口的事件监听器

    package me.gacl.listener.demo;
    
    import java.awt.Frame;
    import java.awt.event.WindowEvent;
    import java.awt.event.WindowListener;
    
    public class Demo1 {
    
        /**
         *java的事件监听机制
         *1、事件监听涉及到三个组件:事件源、事件对象、事件监听器
         *2、当事件源上发生某一个动作时,它会调用事件监听器的一个方法,并在调用该方法时把事件对象传递进去,
         *    开发者在监听器中通过事件对象,就能够拿到事件源,从而对事件源进行操作。

    */ public static void main(String[] args) { Frame f = new Frame(); f.setSize(400, 400); f.setVisible(true); //注冊事件监听器 f.addWindowListener(new WindowListener(){ public void windowActivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { } /** * 当window窗口关闭时就会WindowListener这个监听器监听到, * 监听器就会调用windowClosing方法处理window窗口关闭时的动作 */ public void windowClosing(WindowEvent e) { //通过事件对象e来获取事件源对象 Frame f = (Frame) e.getSource(); System.out.println(f+"窗口正在关闭"); f.dispose(); } public void windowDeactivated(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowOpened(WindowEvent e) { } }); } }

    1.3、设计一个能够被别的对象监听的对象

      我们平时做开发的时候,我们是写监听器去监听其它对象。那么我们假设想设计一个对象,让这个对象能够被别的对象监听又该怎么做呢。能够依照严格的事件处理模型来设计一个对象。这个对象就能够被别的对象监听,事件处理模型涉及到三个组件:事件源、事件对象、事件监听器。

      以下我们来依照事件处理模型来设计一个Person对象,详细代码例如以下:

    package me.gacl.observer;
    
    /**
    * @ClassName: Person(事件源)
    * @Description: 设计一个Person类作为事件源,这个类的对象的行为(比方吃饭、跑步)能够被其它的对象监听
    * @author: 孤傲苍狼
    * @date: 2014-9-9 下午9:26:06
    *
    */  
    public class Person {
        /**
        * @Field: listener
        *          在Person类中定义一个PersonListener变量来记住传递进来的监听器
        */ 
        private PersonListener listener;
    
        /**
        * @Method: eat
        * @Description: 设计Person的行为:吃
        * @Anthor:孤傲苍狼
        *
        */ 
        public void eat() {
            if (listener != null) {
                /**
                 * 调用监听器的doeat方法监听Person类对象eat(吃)这个动作,将事件对象Event传递给doeat方法。
                 * 事件对象封装了事件源。new Event(this)中的this代表的就是事件源
                 */
                listener.doeat(new Event(this));
            }
        }
    
        /**
        * @Method: run
        * @Description: 设计Person的行为:跑
        * @Anthor:孤傲苍狼
        *
        */ 
        public void run() {
            if (listener != null) {
                /**
                 * 调用监听器的dorun方法监听Person类对象run(跑)这个动作,将事件对象Event传递给doeat方法,
                 * 事件对象封装了事件源,new Event(this)中的this代表的就是事件源
                 */
                listener.dorun(new Event(this));
            }
        }
    
        /**
        * @Method: registerListener
        * @Description: 这种方法是用来注冊对Person类对象的行为进行监听的监听器
        * @Anthor:孤傲苍狼
        *
        * @param listener
        */ 
        public void registerListener(PersonListener listener) {
            this.listener = listener;
        }
    }
    
    /**
    * @ClassName: PersonListener(事件监听器)
    * @Description: 设计Person类(事件源)的监听器接口
    * @author: 孤傲苍狼
    * @date: 2014-9-9 下午9:28:06
    *
    */ 
    interface PersonListener {
    
        /**
        * @Method: doeat
        * @Description: 这种方法是用来监听Person对象eat(吃)这个行为动作,
        *                 当实现类实现doeat方法时就能够监听到Person类对象eat(吃)这个动作
        * @Anthor:孤傲苍狼
        *
        * @param e
        */ 
        void doeat(Event e);
    
        /**
        * @Method: dorun
        * @Description: 这种方法是用来监听Person对象run(跑)这个行为动作,
        *                 当实现类实现dorun方法时就能够监听到Person类对象run(跑)这个动作
        * @Anthor:孤傲苍狼
        *
        * @param e
        */ 
        void dorun(Event e);
    
    }
    
    /**
    * @ClassName: Event(事件对象)
    * @Description:设计事件类,用来封装事件源
    * @author: 孤傲苍狼
    * @date: 2014-9-9 下午9:37:56
    *
    */ 
    class Event {
    
        /**
        * @Field: source
        *          事件源(Person就是事件源)
        */ 
        private Person source;
    
        public Event() {
    
        }
    
        public Event(Person source) {
            this.source = source;
        }
    
        public Person getSource() {
            return source;
        }
    
        public void setSource(Person source) {
            this.source = source;
        }
    }

      经过这种设计之后。Peron类的对象就是能够被其它对象监听了。測试代码例如以下:

    package me.gacl.observer;
    
    public class PersonTest {
    
        /**
         * @Method: main
         * @Description: 測试Person类
         * @Anthor:孤傲苍狼
         *
         * @param args
         */
        public static void main(String[] args) {
            //
            Person p = new Person();
            //注冊监听p对象行为的监听器
            p.registerListener(new PersonListener() {
                //监听p吃东西这个行为
                public void doeat(Event e) {
                    Person p = e.getSource();
                    System.out.println(p + "在吃东西");
                }
                //监听p跑步这个行为
                public void dorun(Event e) {
                    Person p = e.getSource();
                    System.out.println(p + "在跑步");
                }
            });
            //p在吃东西
            p.eat();
            //p在跑步
            p.run();
        }
    }

    执行结果:

      me.gacl.observer.Person@4a5ab2在吃东西
      me.gacl.observer.Person@4a5ab2在跑步

    二、JavaWeb中的监听器

    2.1、基本概念

      JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对象的创建与销毁事件。以及监听这些域对象中的属性发生改动的事件。

    2.2、Servlet监听器的分类

      在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为ServletContextHttpSessionServletRequest这三个域对象
      Servlet规范针对这三个对象上的操作,又把多种类型的监听器划分为三种类型:

    • 监听域对象自身的创建和销毁的事件监听器。
    • 监听域对象中的属性的添加和删除的事件监听器。
    • 监听绑定到HttpSession域中的某个对象的状态的事件监听器。

    2.3、监听ServletContext域对象的创建和销毁

      ServletContextListener接口用于监听ServletContext对象的创建和销毁事件。实现了ServletContextListener接口的类都能够对ServletContext对象的创建和销毁进行监听。

    • 当ServletContext对象被创建时,激发contextInitialized (ServletContextEvent sce)方法。

    • 当ServletContext对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。

    • ServletContext域对象创建和销毁时机:
          创建:服务器启动针对每个Web应用创建ServletContext
          销毁:服务器关闭前先关闭代表每个web应用的ServletContext

    范例:编写一个MyServletContextListener类,实现ServletContextListener接口。监听ServletContext对象的创建和销毁

      1、编写监听器,代码例如以下:

    package me.gacl.web.listener;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    /**
    * @ClassName: MyServletContextListener
    * @Description: MyServletContextListener类实现了ServletContextListener接口,
    *                 因此能够对ServletContext对象的创建和销毁这两个动作进行监听。

    * @author: 孤傲苍狼 * @date: 2014-9-9 下午10:26:16 * */ public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("ServletContext对象创建"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext对象销毁"); } }

      2、在web.xml文件里注冊监听器

      我们在上面的中讲到,要想监听事件源,那么必须将监听器注冊到事件源上才干够实现对事件源的行为动作进行监听,在JavaWeb中,监听的注冊是在web.xml文件里进行配置的。例如以下:

    <?

    xml version="1.0" encoding="UTF-8"?

    > <web-app version="3.0" 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_3_0.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 注冊针对ServletContext对象进行监听的监听器 --> <listener> <description>ServletContextListener监听器</description> <!--实现了ServletContextListener接口的监听器类 --> <listener-class>me.gacl.web.listener.MyServletContextListener</listener-class> </listener> </web-app>

      经过这两个步骤,我们就完毕了监听器的编写和注冊。Web服务器在启动时。就会自己主动把在web.xml中配置的监听器注冊到ServletContext对象上,这样开发好的MyServletContextListener监听器就能够对ServletContext对象进行监听了。

    2.4、监听HttpSession域对象的创建和销毁

      HttpSessionListener 接口用于监听HttpSession对象的创建和销毁
      创建一个Session时,激发sessionCreated (HttpSessionEvent se) 方法
      销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se) 方法。

    范例:编写一个MyHttpSessionListener类,实现HttpSessionListener接口。监听HttpSession对象的创建和销毁

      1、编写监听器。代码例如以下:

    package me.gacl.web.listener;
    
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    
    /**
    * @ClassName: MyHttpSessionListener
    * @Description: MyHttpSessionListener类实现了HttpSessionListener接口,
    *                 因此能够对HttpSession对象的创建和销毁这两个动作进行监听。

    * @author: 孤傲苍狼 * @date: 2014-9-9 下午11:04:33 * */ public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println( se.getSession() + "创建了!。"); } /* HttpSession的销毁时机须要在web.xml中进行配置,例如以下: * <session-config> <session-timeout>1</session-timeout> </session-config> 这样配置就表示session在1分钟之后就被销毁 */ @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("session销毁了!。"); } }

      2、在web.xml文件里注冊监听器

    <!--注冊针对HttpSession对象进行监听的监听器-->
       <listener>
          <description>HttpSessionListener监听器</description>
          <listener-class>me.gacl.web.listener.MyHttpSessionListener</listener-class>
      </listener>
      <!-- 配置HttpSession对象的销毁时机 -->
      <session-config>
          <!--配置HttpSession对象的1分钟之后销毁 -->
          <session-timeout>1</session-timeout>
      </session-config>

      当我们訪问jsp页面时,HttpSession对象就会创建,此时就能够在HttpSessionListener观察到HttpSession对象的创建过程了,我们能够写一个jsp页面观察HttpSession对象创建的过程。

    例如以下:index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
    
    <!DOCTYPE HTML>
    <html>
      <head>
        <title>HttpSessionListener监听器监听HttpSession对象的创建</title>
      </head>
    
      <body>
           一訪问JSP页面,HttpSession就创建了。创建好的Session的Id是:${pageContext.session.id}
      </body>
    </html>

    执行结果例如以下:

    这里写图片描写叙述

    2.5、监听ServletRequest域对象的创建和销毁

      ServletRequestListener接口用于监听ServletRequest 对象的创建和销毁
      Request对象被创建时,监听器的requestInitialized(ServletRequestEvent sre)方法将会被调用
      Request对象被销毁时,监听器的requestDestroyed(ServletRequestEvent sre)方法将会被调用

      ServletRequest域对象创建和销毁时机:
        创建:用户每一次訪问都会创建request对象
        销毁:当前訪问结束,request对象就会销毁

    范例:编写一个MyServletRequestListener类,实现ServletRequestListener接口。监听ServletRequest对象的创建和销毁

      1、编写监听器。代码例如以下:

    package me.gacl.web.listener;
    
    import javax.servlet.ServletRequestEvent;
    import javax.servlet.ServletRequestListener;
    
    /**
    * @ClassName: MyServletRequestListener
    * @Description: MyServletRequestListener类实现了ServletRequestListener接口,
    *                 因此能够对ServletRequest对象的创建和销毁这两个动作进行监听。

    * @author: 孤傲苍狼 * @date: 2014-9-9 下午11:50:08 * */ public class MyServletRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println(sre.getServletRequest() + "销毁了。!"); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println(sre.getServletRequest() + "创建了。。"); } }

      2、在web.xml文件里注冊监听器

    <!--注冊针对ServletRequest对象进行监听的监听器-->
       <listener>
           <description>ServletRequestListener监听器</description>
           <listener-class>me.gacl.web.listener.MyServletRequestListener</listener-class>
       </listener>

    測试结果例如以下:

    这里写图片描写叙述

      从执行结果中能够看到,用户每一次訪问都会创建request对象。当訪问结束后,request对象就会销毁。

      以上就是对监听器的一些简单解说。

  • 相关阅读:
    Android实战经验之图像处理及特效处理的集锦(总结版)
    Android类似于滚动的通知栏实现
    Python概览
    高效程序员的45个习惯读书笔记
    Web前台传对象字符串到后台并让后台反序列化对象字符串的方法(ASP.NET)
    发布订阅者模式之C#委托实现
    表数据复制(迁移)
    Code Smell
    Python学习过程遇到的Bug不断更新
    Resharper 7小技巧系列:导航、书签、和最近编辑
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7111351.html
Copyright © 2020-2023  润新知