一、监听器介绍

1.1、监听器的概念

  

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

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

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

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

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

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

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

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

  1. 1 package me.gacl.observer;
  2. 2
  3. 3 public class PersonTest {
  4. 4
  5. 5 /**
  6. 6 * @Method: main
  7. 7 * @Description: 测试Person类
  8. 8 * @Anthor:孤傲苍狼
  9. 9 *
  10. 10 * @param args
  11. 11 */
  12. 12 public static void main(String[] args) {
  13. 13 //
  14. 14 Person p = new Person();
  15. 15 //注册监听p对象行为的监听器
  16. 16 p.registerListener(new PersonListener() {
  17. 17 //监听p吃东西这个行为
  18. 18 public void doeat(Event e) {
  19. 19 Person p = e.getSource();
  20. 20 System.out.println(p + "在吃东西");
  21. 21 }
  22. 22 //监听p跑步这个行为
  23. 23 public void dorun(Event e) {
  24. 24 Person p = e.getSource();
  25. 25 System.out.println(p + "在跑步");
  26. 26 }
  27. 27 });
  28. 28 //p在吃东西
  29. 29 p.eat();
  30. 30 //p在跑步
  31. 31 p.run();
  32. 32 }
  33. 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. 1 package me.gacl.web.listener;
  2. 2
  3. 3 import javax.servlet.ServletContextEvent;
  4. 4 import javax.servlet.ServletContextListener;
  5. 5
  6. 6 /**
  7. 7 * @ClassName: MyServletContextListener
  8. 8 * @Description: MyServletContextListener类实现了ServletContextListener接口,
  9. 9 * 因此可以对ServletContext对象的创建和销毁这两个动作进行监听。
  10. 10 * @author: 孤傲苍狼
  11. 11 * @date: 2014-9-9 下午10:26:16
  12. 12 *
  13. 13 */
  14. 14 public class MyServletContextListener implements ServletContextListener {
  15. 15
  16. 16 @Override
  17. 17 public void contextInitialized(ServletContextEvent sce) {
  18. 18 System.out.println("ServletContext对象创建");
  19. 19 }
  20. 20
  21. 21 @Override
  22. 22 public void contextDestroyed(ServletContextEvent sce) {
  23. 23 System.out.println("ServletContext对象销毁");
  24. 24 }
  25. 25 }

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

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

  1. 1 <?xml version="1.0" encoding="UTF-8"?>
  2. 2 <web-app version="3.0"
  3. 3 xmlns="http://java.sun.com/xml/ns/javaee"
  4. 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  6. 6 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  7. 7 <display-name></display-name>
  8. 8 <welcome-file-list>
  9. 9 <welcome-file>index.jsp</welcome-file>
  10. 10 </welcome-file-list>
  11. 11
  12. 12 <!-- 注册针对ServletContext对象进行监听的监听器 -->
  13. 13 <listener>
  14. 14 <description>ServletContextListener监听器</description>
  15. 15 <!--实现了ServletContextListener接口的监听器类 -->
  16. 16 <listener-class>me.gacl.web.listener.MyServletContextListener</listener-class>
  17. 17 </listener>
  18. 18
  19. 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. 1 package me.gacl.web.listener;
  2. 2
  3. 3 import javax.servlet.http.HttpSessionEvent;
  4. 4 import javax.servlet.http.HttpSessionListener;
  5. 5
  6. 6 /**
  7. 7 * @ClassName: MyHttpSessionListener
  8. 8 * @Description: MyHttpSessionListener类实现了HttpSessionListener接口,
  9. 9 * 因此可以对HttpSession对象的创建和销毁这两个动作进行监听。
  10. 10 * @author: 孤傲苍狼
  11. 11 * @date: 2014-9-9 下午11:04:33
  12. 12 *
  13. 13 */
  14. 14 public class MyHttpSessionListener implements HttpSessionListener {
  15. 15
  16. 16 @Override
  17. 17 public void sessionCreated(HttpSessionEvent se) {
  18. 18 System.out.println( se.getSession() + "创建了!!");
  19. 19 }
  20. 20
  21. 21 /* HttpSession的销毁时机需要在web.xml中进行配置,如下:
  22. 22 * <session-config>
  23. 23 <session-timeout>1</session-timeout>
  24. 24 </session-config>
  25. 25 这样配置就表示session在1分钟之后就被销毁
  26. 26 */
  27. 27 @Override
  28. 28 public void sessionDestroyed(HttpSessionEvent se) {
  29. 29 System.out.println("session销毁了!!");
  30. 30 }
  31. 31 }

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

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

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

如下:index.jsp

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

运行结果如下:

  

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

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

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

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

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

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

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

  1. 1 <!--注册针对ServletRequest对象进行监听的监听器-->
  2. 2 <listener>
  3. 3 <description>ServletRequestListener监听器</description>
  4. 4 <listener-class>me.gacl.web.listener.MyServletRequestListener</listener-class>
  5. 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. java如何调用webservice接口

    java调用WebService可以直接使用Apache提供的axis.jar自己编写代码,或者利用Eclipse自动生成WebService Client代码,利用其中的Proxy类进行调用.理论上 ...

  2. CodeForces 679B(Bear and Tower of Cubes)

    题意:Limak要垒一座由立方体垒成的塔.现有无穷多个不同棱长(a>=1)的立方体.要求:1.塔的体积为X(X<=m).2.在小于X的前提下,每次都选体积最大的砖块.3.在砖块数最多的前提 ...

  3. Bootstrap学习笔记(二) 表单

    在Bootstrap学习笔记(一) 排版的基础上继续学习Bootstrap的表单,编辑器及head内代码不变. 3-1 基础表单 单中常见的元素主要包括:文本输入框.下拉选择框.单选按钮.复选按钮.文 ...

  4. DDL操作前后都有COMMIT

    引用出处: http://www.itpub.net/thread-1746448-1-1.html 要说明这个问题,首先需要说明什么是DDL语句.DDL语句是数据定义语句,包括各种数据对象的创建.修 ...

  5. C#使用反射工厂模式遇到System.TypeLoadException(类名错误导致)

    项目中,在运行另一个反射类时出现问题,未能从程序集中加载类 class PopUpActionFactory { public static InterfacePopUpAction getActio ...

  6. apache重写

    ---- 本文旨在提供如何用Apache重写规则来解决一些常见的URL重写方法的问题,通过常见的实例给用户一些使用重写规则的基本方法和线索. 一.为什么需要用重写规则 ---- 网站的生命在于不断地进 ...

  7. 分享一个很好用的 日期选择控件datepicker 使用方法分享

    很多同学在做网站的时候,有时候需要用户选择日期,年月日这些的,以前我也在用一个,但是那个的界面都不太好看,于是找啊找,找啊找,找到一个好东西,就是这个,datepicker,是jquery.ui里面的 ...

  8. WCF 宿主与通信模式(二)

    宿主 每个WCF服务都必须托管在Windows进程中,该进程称为宿主进程(host process) 单个宿主进程可以托管多个服务,相同的服务类型也可以托管在多个宿主进程中. wcf中托管服务一般有一 ...

  9. DTCMS自定义标签:面包屑导航,栏目中通过栏目调用名称获得栏目名称

    DTcms.Web.UI\Label\category.cs中增加标签 /// <summary> /// 自定义:通过类别name获得类别title /// </summary&g ...

  10. [DevExpress]RepositoryItemComboBox 数据绑定

    关键代码: public static void Bind<T>(this RepositoryItemComboBox combox, ICollection source) { /*说 ...