一、监听器介绍

1.1、监听器的概念

  

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

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

 1 package me.gacl.listener.demo;
 2
 3 import java.awt.Frame;
 4 import java.awt.event.WindowEvent;
 5 import java.awt.event.WindowListener;
 6
 7 public class Demo1 {
 8
 9     /**
10      *java的事件监听机制
11      *1、事件监听涉及到三个组件:事件源、事件对象、事件监听器
12      *2、当事件源上发生某一个动作时,它会调用事件监听器的一个方法,并在调用该方法时把事件对象传递进去,
13      *    开发人员在监听器中通过事件对象,就可以拿到事件源,从而对事件源进行操作。
14      */
15     public static void main(String[] args) {
16
17         Frame f = new Frame();
18         f.setSize(400, 400);
19         f.setVisible(true);
20
21         //注册事件监听器
22         f.addWindowListener(new WindowListener(){
23
24             public void windowActivated(WindowEvent e) {
25
26             }
27
28             public void windowClosed(WindowEvent e) {
29
30             }
31
32             /**
33              * 当window窗体关闭时就会WindowListener这个监听器监听到,
34              * 监听器就会调用windowClosing方法处理window窗体关闭时的动作
35              */
36             public void windowClosing(WindowEvent e) {
37                 //通过事件对象e来获取事件源对象
38                 Frame f = (Frame) e.getSource();
39                 System.out.println(f+"窗体正在关闭");
40                 f.dispose();
41             }
42
43             public void windowDeactivated(WindowEvent e) {
44
45             }
46
47             public void windowDeiconified(WindowEvent e) {
48
49             }
50
51             public void windowIconified(WindowEvent e) {
52
53             }
54
55             public void windowOpened(WindowEvent e) {
56
57             }
58         });
59     }
60 }

1.3、设计一个可以被别的对象监听的对象

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

  下面我们来按照事件处理模型来设计一个Person对象具体代码如下:

  1 package me.gacl.observer;
  2
  3 /**
  4 * @ClassName: Person(事件源)
  5 * @Description: 设计一个Person类作为事件源,这个类的对象的行为(比如吃饭、跑步)可以被其他的对象监听
  6 * @author: 孤傲苍狼
  7 * @date: 2014-9-9 下午9:26:06
  8 *
  9 */
 10 public class Person {
 11     /**
 12     * @Field: listener
 13     *          在Person类中定义一个PersonListener变量来记住传递进来的监听器
 14     */
 15     private PersonListener listener;
 16
 17     /**
 18     * @Method: eat
 19     * @Description: 设计Person的行为:吃
 20     * @Anthor:孤傲苍狼
 21     *
 22     */
 23     public void eat() {
 24         if (listener != null) {
 25             /**
 26              * 调用监听器的doeat方法监听Person类对象eat(吃)这个动作,将事件对象Event传递给doeat方法,
 27              * 事件对象封装了事件源,new Event(this)中的this代表的就是事件源
 28              */
 29             listener.doeat(new Event(this));
 30         }
 31     }
 32
 33     /**
 34     * @Method: run
 35     * @Description: 设计Person的行为:跑
 36     * @Anthor:孤傲苍狼
 37     *
 38     */
 39     public void run() {
 40         if (listener != null) {
 41             /**
 42              * 调用监听器的dorun方法监听Person类对象run(跑)这个动作,将事件对象Event传递给doeat方法,
 43              * 事件对象封装了事件源,new Event(this)中的this代表的就是事件源
 44              */
 45             listener.dorun(new Event(this));
 46         }
 47     }
 48
 49     /**
 50     * @Method: registerListener
 51     * @Description: 这个方法是用来注册对Person类对象的行为进行监听的监听器
 52     * @Anthor:孤傲苍狼
 53     *
 54     * @param listener
 55     */
 56     public void registerListener(PersonListener listener) {
 57         this.listener = listener;
 58     }
 59 }
 60
 61 /**
 62 * @ClassName: PersonListener(事件监听器)
 63 * @Description: 设计Person类(事件源)的监听器接口
 64 * @author: 孤傲苍狼
 65 * @date: 2014-9-9 下午9:28:06
 66 *
 67 */
 68 interface PersonListener {
 69
 70     /**
 71     * @Method: doeat
 72     * @Description: 这个方法是用来监听Person对象eat(吃)这个行为动作,
 73     *                 当实现类实现doeat方法时就可以监听到Person类对象eat(吃)这个动作
 74     * @Anthor:孤傲苍狼
 75     *
 76     * @param e
 77     */
 78     void doeat(Event e);
 79
 80     /**
 81     * @Method: dorun
 82     * @Description: 这个方法是用来监听Person对象run(跑)这个行为动作,
 83     *                 当实现类实现dorun方法时就可以监听到Person类对象run(跑)这个动作
 84     * @Anthor:孤傲苍狼
 85     *
 86     * @param e
 87     */
 88     void dorun(Event e);
 89
 90 }
 91
 92 /**
 93 * @ClassName: Event(事件对象)
 94 * @Description:设计事件类,用来封装事件源
 95 * @author: 孤傲苍狼
 96 * @date: 2014-9-9 下午9:37:56
 97 *
 98 */
 99 class Event {
100
101     /**
102     * @Field: source
103     *          事件源(Person就是事件源)
104     */
105     private Person source;
106
107     public Event() {
108
109     }
110
111     public Event(Person source) {
112         this.source = source;
113     }
114
115     public Person getSource() {
116         return source;
117     }
118
119     public void setSource(Person source) {
120         this.source = source;
121     }
122 }

  经过这样的设计之后,Peron类的对象就是可以被其他对象监听了。测试代码如下:

 1 package me.gacl.observer;
 2
 3 public class PersonTest {
 4
 5     /**
 6      * @Method: main
 7      * @Description: 测试Person类
 8      * @Anthor:孤傲苍狼
 9      *
10      * @param args
11      */
12     public static void main(String[] args) {
13         //
14         Person p = new Person();
15         //注册监听p对象行为的监听器
16         p.registerListener(new PersonListener() {
17             //监听p吃东西这个行为
18             public void doeat(Event e) {
19                 Person p = e.getSource();
20                 System.out.println(p + "在吃东西");
21             }
22             //监听p跑步这个行为
23             public void dorun(Event e) {
24                 Person p = e.getSource();
25                 System.out.println(p + "在跑步");
26             }
27         });
28         //p在吃东西
29         p.eat();
30         //p在跑步
31         p.run();
32     }
33 }

运行结果:

  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规范针对这三个对象上的操作,又把多种类型的监听器划分为三种类型:

  1. 监听域对象自身的创建和销毁的事件监听器。
  2. 监听域对象中的属性的增加和删除的事件监听器。
  3. 监听绑定到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、编写监听器,代码如下:

 1 package me.gacl.web.listener;
 2
 3 import javax.servlet.ServletContextEvent;
 4 import javax.servlet.ServletContextListener;
 5
 6 /**
 7 * @ClassName: MyServletContextListener
 8 * @Description: MyServletContextListener类实现了ServletContextListener接口,
 9 *                 因此可以对ServletContext对象的创建和销毁这两个动作进行监听。
10 * @author: 孤傲苍狼
11 * @date: 2014-9-9 下午10:26:16
12 *
13 */
14 public class MyServletContextListener implements ServletContextListener {
15
16     @Override
17     public void contextInitialized(ServletContextEvent sce) {
18         System.out.println("ServletContext对象创建");
19     }
20
21     @Override
22     public void contextDestroyed(ServletContextEvent sce) {
23         System.out.println("ServletContext对象销毁");
24     }
25 }

  2、在web.xml文件中注册监听器

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

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="3.0"
 3     xmlns="http://java.sun.com/xml/ns/javaee"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 6     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 7   <display-name></display-name>
 8   <welcome-file-list>
 9     <welcome-file>index.jsp</welcome-file>
10   </welcome-file-list>
11
12   <!-- 注册针对ServletContext对象进行监听的监听器 -->
13   <listener>
14       <description>ServletContextListener监听器</description>
15       <!--实现了ServletContextListener接口的监听器类 -->
16       <listener-class>me.gacl.web.listener.MyServletContextListener</listener-class>
17   </listener>
18
19 </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、编写监听器,代码如下:

 1 package me.gacl.web.listener;
 2
 3 import javax.servlet.http.HttpSessionEvent;
 4 import javax.servlet.http.HttpSessionListener;
 5
 6 /**
 7 * @ClassName: MyHttpSessionListener
 8 * @Description: MyHttpSessionListener类实现了HttpSessionListener接口,
 9 *                 因此可以对HttpSession对象的创建和销毁这两个动作进行监听。
10 * @author: 孤傲苍狼
11 * @date: 2014-9-9 下午11:04:33
12 *
13 */
14 public class MyHttpSessionListener implements HttpSessionListener {
15
16     @Override
17     public void sessionCreated(HttpSessionEvent se) {
18         System.out.println( se.getSession() + "创建了!!");
19     }
20
21     /* HttpSession的销毁时机需要在web.xml中进行配置,如下:
22      * <session-config>
23               <session-timeout>1</session-timeout>
24           </session-config>
25           这样配置就表示session在1分钟之后就被销毁
26      */
27     @Override
28     public void sessionDestroyed(HttpSessionEvent se) {
29         System.out.println("session销毁了!!");
30     }
31 }

  2、在web.xml文件中注册监听器

 1  <!--注册针对HttpSession对象进行监听的监听器-->
 2    <listener>
 3       <description>HttpSessionListener监听器</description>
 4       <listener-class>me.gacl.web.listener.MyHttpSessionListener</listener-class>
 5   </listener>
 6   <!-- 配置HttpSession对象的销毁时机 -->
 7   <session-config>
 8       <!--配置HttpSession对象的1分钟之后销毁 -->
 9       <session-timeout>1</session-timeout>
10   </session-config>

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

如下:index.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
 2
 3 <!DOCTYPE HTML>
 4 <html>
 5   <head>
 6     <title>HttpSessionListener监听器监听HttpSession对象的创建</title>
 7   </head>
 8
 9   <body>
10        一访问JSP页面,HttpSession就创建了,创建好的Session的Id是:${pageContext.session.id}
11   </body>
12 </html>

运行结果如下:

  

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

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

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

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

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

 1 package me.gacl.web.listener;
 2
 3 import javax.servlet.ServletRequestEvent;
 4 import javax.servlet.ServletRequestListener;
 5
 6 /**
 7 * @ClassName: MyServletRequestListener
 8 * @Description: MyServletRequestListener类实现了ServletRequestListener接口,
 9 *                 因此可以对ServletRequest对象的创建和销毁这两个动作进行监听。
10 * @author: 孤傲苍狼
11 * @date: 2014-9-9 下午11:50:08
12 *
13 */
14 public class MyServletRequestListener implements ServletRequestListener {
15
16     @Override
17     public void requestDestroyed(ServletRequestEvent sre) {
18         System.out.println(sre.getServletRequest() + "销毁了!!");
19
20     }
21
22     @Override
23     public void requestInitialized(ServletRequestEvent sre) {
24         System.out.println(sre.getServletRequest() + "创建了!!");
25     }
26 }

  2、在web.xml文件中注册监听器

1  <!--注册针对ServletRequest对象进行监听的监听器-->
2    <listener>
3       <description>ServletRequestListener监听器</description>
4       <listener-class>me.gacl.web.listener.MyServletRequestListener</listener-class>
5   </listener>

测试结果如下:

  

  从运行结果中可以看到,用户每一次访问都会创建request对象,当访问结束后,request对象就会销毁。

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

javaweb学习总结(四十四)——监听器(Listener)学习的更多相关文章

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

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

  2. javaWeb学习总结(11)- 监听器(Listener)学习

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

  3. JavaWeb学习 (二十六)————监听器(Listener)学习(二)

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

  4. javaWeb学习总结(11)- 监听器(Listener)学习(2)

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

  5. 设计模式学习(二十四):Spring 中使用到的设计模式

    设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...

  6. 我的MYSQL学习心得(十四) 备份和恢复

    我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  7. VSTO学习笔记(十四)Excel数据透视表与PowerPivot

    原文:VSTO学习笔记(十四)Excel数据透视表与PowerPivot 近期公司内部在做一种通用查询报表,方便人力资源分析.统计数据.由于之前公司系统中有一个类似的查询使用Excel数据透视表完成的 ...

  8. Linux学习总结(十四)—— 查看CPU信息

    文章首发于[博客园-陈树义],点击跳转到原文Linux学习总结(十四)-- 查看CPU信息. Linux学习总结(十四)-- 查看CPU信息 商用服务器CPU最常用的是 Intel Xeon 系列,该 ...

  9. Python学习笔记(十四)

    Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...

  10. python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法

    python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...

随机推荐

  1. [WCF]IIS部署到新系统

    最近为以前的一个企业部署软件的时候,接触到WCF,通过博客园大佬的系列文章和一些书籍,基本了解了一些.简单说也算是SOA一种方式,提供某种服务,可以理解为一个类库,供其他项目使用,可以做到业务分离.但 ...

  2. Remote Desktop Organizer远程桌面管理软件的基本使用和介绍

    <Remote Desktop Organizer>是一款用于远程桌面管理的软件.软件支持windows平台运行. Remote Desktop Organizer 是一款 Windows ...

  3. GTEST-ASSERT出错

    ASSERT_TRUE(1==1); ASSERT_EQ(1,1); 会给出以下错误: "cfunctest_normal.cpp", line 121.9: 1540-0258 ...

  4. 动态linq表达式新方法,Dynamic LINQ Extension Method

    Remember those old posts on Dynamic LINQ? You are probably aware that Microsoft has made its impleme ...

  5. NSS_01 开始

    工作中一直使用asp.net webform, 最近有一个新的小项目, 决定用asp.net mvc3, 边学习边工作吧,记录一下开发过程中的问题,因为工作嘛,只记录问题,可能不会很详细. 准备使用a ...

  6. QMessageBox 弹出框上的按钮设置为中文

    Qt 默认的弹出框上的按钮式英文,虽然也知道是什么意思,但终究不如中文看着顺眼. QMessageBox box(QMessageBox::Warning,"标题","弹 ...

  7. HTML5如何重塑O2O用户体验

    低频次垂直O2O服务应该继续开发原生APP吗?大家有没有发现做一个APP的推广成本和获取用户的成本越来越高?第二,用户安装APP之后,用户并不是经常点击使用APP的,那这是为什么?数据表明90%的O2 ...

  8. Inside Microsoft SQL Server 2008: T-SQL Querying 读书笔记之查询优化

    一. 自顶向下优化方法论 1. 分析实例级别的等待 在实例级找出什么类型的等待占用大部分的时间,通过sys.dm_os_wait_stats select wait_type, --等待类型 wait ...

  9. C++ 关联容器详解——从内部结构到应用

    关联容器不同于顺序容器的是:顺序容器底层用数组实现,为线性结构:关联容器在实现中,用到的非线性存储方式: 顺序容器是通过元素在容器中的位置顺序存储和访问元素,而关联容器是通过键(key)存储和读取元素 ...

  10. WPF学习笔记4——Layout之2

    下面简单介绍常见的面板. 一.Grid 1.Grid关于调整行列距离有三种方法:绝对大小,自动大小,比例大小.如下: <ColumnDefinition Width="100" ...