javaweb学习总结(四十四)——监听器(Listener)学习

一、监听器介绍

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规范中定义了多种类型的监听器,它们用于监听的事件源分别为ServletContext,HttpSession和ServletRequest这三个域对象

  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对象就会销毁。

 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第一期冲刺01

1、我昨天的成就 确定了软件所满足的需求 2、遇到什么困难 跟航哥有太多想要实现的&#xff0c;但后续慢慢找到了重点 3、今天的任务 安装安卓studio 配置好编程所需要的环境 转载于:https://www.cnblogs.com/zjm15511858030/p/11065660.html

vue无缝滚动的插件开发填坑分享

写插件的初衷 1.项目经常需要无缝滚动效果&#xff0c;当时写jq的时候用用msClass这个老插件&#xff0c;相对不上很好用。2.后来转向vue在vue-awesome没有找到好的无缝滚动插件&#xff0c;除了配置swiper可以实现但是相对来说太重了&#xff0c;于是自己造了个轮子。 3.在这分…

Spring 注解 @Resource和@Autowired

Resource和Autowired两者都是做bean的注入使用。 其实Resource并不是Spring的注解&#xff0c;他的包是javax.annotation.Resource 需要导入。但是Spring支持该注解的注入。 共同点&#xff1a;两者都可以写在字段和setter方法上。两者如果都写在字段上&#xff0c;就不需要写…

洛谷 P1091 合唱队型

很容易想到维护一个最长上升子序列和一个最长下降子序列。然后枚举一个点k&#xff0c;取所有以k结尾的最长上升子序列和以k开头的最长下降子序列的长度的和中最大的&#xff0c;表示留下的人数。再用总人数减去这个&#xff0c;等于出队人数 另外类似的一道题&#xff1a;最长…

PHP常用的自定义函数

PHP常用的自定义函数 目录 php常用自定义函数类下载php 设置字符编码为utf-8路径格式化(替换双斜线为单斜线)转码打印输出api返回信息字符串截取 方法一:方法二:数组 字符串 对象 json格式的字符串互转强制类型转换php序列化serialize与返回序列化unserialeze创建日志文件获取i…

Spring注解@Component、@Repository、@Service、@Controller区别

很长时间没做web项目都把以前学的那点框架知识忘光了&#xff0c;今天把以前做的一个项目翻出来看一下发现用Component标记一个组件&#xff0c;而网上有的用Service标记组件&#xff0c;我晕就查了一下资料&#xff1a; Spring 2.5 中除了提供 Component 注释外&#xff0c;还…

春第十周作业

作业&#xff1a; 这个作业属于那个课程C语言程序设计II这个作业要求在哪里https://edu.cnblogs.com/campus/zswxy/software-engineering-class2-2018/homework/3162我在这个课程的目标是阅读并学习这个作业在那个具体方面帮助我实现目标知道了我们以后工作所需的是雇主所需的参…

在原生js中的事件监听方法

一、传统事件绑定方法我们在学习的时候&#xff0c;最初接触的事件绑定方式大多是传统事件绑定方法。传统事件绑定方法事例如下&#xff1a; window.οnlοadfunction(){alert("页面已加载"); } document.getElementById("btn").οnclickfunction(){alert(…

MySql修改数据库编码为UTF8

mysql 创建 数据库时指定编码很重要&#xff0c;很多开发者都使用了默认编码&#xff0c;乱码问题可是防不胜防。制定数据库的编码可以很大程度上避免倒入导出带来的乱码问题。 网页数据一般采用UTF8编码&#xff0c;而数据库默认为latin 。我们可以通过修改数据库默认编码方式…

第六次作业(C语言)

心得体会 该题主要涉及知识点有&#xff1a;1、函数的定义&#xff1b;2、函数的调用&#xff08;即prime函数的调用&#xff09;&#xff1b;3、素数的判断&#xff1b;4、大小排序。 看到题时我首先想到了嵌套循环&#xff0c;可是仔细一看题目要求的是用prime函数的调用&…

Javascript系列——对象元素的数组去重实现

概要 这是一篇记录文&#xff0c;记录数组操作对象去重的实现。 需求 有这样一个数组 [{_id: 123,name: 张三 },{_id: 124,name: 李四 },{_id: 123,name: 张三 }] 实际上我们只需要 [{_id: 123,name: 张三 },{_id: 124,name: 李四 }] 去重 简单数组的去重 Array.from(new Set([…

关于__getattribute__

先看一个案例 class Tree(object):def __init__(self,name):self.namenameself.cateplantdef __getattribute__(self, item):if item大树:print(log 大树)return 我爱大树else:return object.__getattribute__(self,item)aaTree(rrrr) print(aa.name) print(aa.cate) 运行结果…

通过Navicat for MySQL远程连接的时候报错mysql 1130的解决方法

来源&#xff1a;互联网 作者&#xff1a;佚名 时间&#xff1a;10-16 18:41:20 【大 中 小】 错误代码是1130&#xff0c;ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server 是无法给远程连接的用户权限问题 Navicat for mysql 1130错误 用…

Java Language Changes for Java SE 9

Java9引入了module模块的概念&#xff0c;是类与接口和数据资源的一种封装&#xff0c;并可以声明与其他模块的依赖关系。这里总结一下Java9带来的新特性。更简练的try-with-resources语句final Resource resource1 new Resource("resource1");//a final resourceRe…

ProtocolHandler继承体系

转载于:https://www.cnblogs.com/GooPolaris/p/10815072.html

mysql数据库存储过程及调用方法

mysql数据库存储过程及调用方法 mysql5.0以后就支持存储过程了&#xff0c;目前mysql的6.0Alpha版也已经推出。6.0不仅支持大型数据库如oracle等的绝大部分功 能&#xff0c;如存储过程、视图、触发器、job等等&#xff0c;而且修正了这些功能所存在的bug&#xff0c;其中6.0.1…

红蜻蜓

日本人なら一度は耳にしたことのある曲でしょう。忘れかけている里山の風景が目に浮かびます。このあたりは昔養蚕が盛んで、何処へ行っても桑畑があったものでしたが、最近はとんと見かけません。小さい頃、よく桑の実をつんで食べたものでした。&#xff08;このあたりでは&q…

elastic学习笔记

要点 不同工具之间版本匹配很重要由点及面&#xff0c;先实践起来再学细节的原理和使用 技术栈 laravel5.5框架scout组件elasticsearch6.3.0搜索引擎辅助 elasticsearch-head 查看集群数据可视化 中文分词插件Ik介绍 laravel是一款现代化的php框架es是搜索引擎es-head是管理查看…

mysql 存储过程中limit

mysql 存储过程中limit 1、mysql的高版本&#xff08;5.5&#xff09;&#xff0c;存储过程中的limit可以使用变量&#xff0c;如下&#xff1a;select * from student limit iStart,iNum; 2、mysql的低版本&#xff08;5.1&#xff09;&#xff0c;存储过程中的limit不能使用…

高频ES6

var promise new Promise((resolve, reject)> {if (操作成功) {resolve (value)}else{reject(error)} }) promise.than(function (value) {/*成功*/}, function(value) {/*失败*/}) Promise是异步编程的一种解决方案, 比传统的解决方案--回调函数和事件更加强大.由社区最早…