首页 > 其他分享 >监听器

监听器

时间:2023-10-17 20:02:14浏览次数:26  
标签:定义 对象 观察者 Session 监听器 设计模式

第1章 监听器相关设计模式

在Servlet规范中存在三大组件:Servlet 接口、Listener 接口、Filter接口。我们在这里要学习监听器接口Listener。监听器是一种设计模式,是观察者设计模式的一种实现。所以我们需要先学习观察者设计模式,再学习监听器设计模式。

1.1 设计模式

设计模式是指,可以重复利用的解决方案。由GoF(Gang of Four,四人组)于1995年提出。他们提出了三类23种设计模式。这三类分别为:

1.1.1 创建型

通过特定方式创建特定对象的设计模式。例如,工厂方法模式、单例模式等。

1.1.2 结构性

为了解决某一特定问题所搭建的特定代码结构的设计模式。例如,适配器模式、代理模式等。

1.1.3 行为型

通过构建不同的角色来完成某一特定功能的设计模式。例如,模板方法模式、观察者模式等。

1.2 观察者设计模

从现实角度来说,我们每一个人都是一个观察者,同时也是一个被观察者。作为被观察者,我们会发出一些信息,观察者在接收到这些信息后,会做出相应的反映;而作为观察者,我们是可以被“被观察者”所发出的信息影响的。一个被观察者,可能存在多个观察者。也就是说,一个被观察者所发出的信息,可能会影响到多个观察者。

观察者设计模式,定义了一种一对多的关联关系。一个对象A与多个对象B、C、D之间建立“被观察与观察关系”。当对象A的状态发生改变时,通知所有观察者对象B、C、D。当观察者对象B、C、D在接收到A的通知后,根据自身实际情况,做出相应改变。

当然,观察者与被观察者指的都是具有某一类功能的对象,所以这里的观察者与被观察者都是指的接口,而真正的观察者对象与被观察者对象,是指实现了这些接口的类的对象。

项目:observePattern(Java Project)

1.2.1 定义观察者接口

监听器_IP


1.2.2 定义被观察者接口

监听器_IP_02


1.2.3 定义观察者

这里定义了两个观察者:1号与2号观察者。

监听器_监听器_03


监听器_监听器_04


1.2.4 定义被观察者

被观察者类除了要实现观察者接口IObservable外,还需要在类中声明并创建一个观察者集合,用于向其中添加观察者。

监听器_IP_05


1.2.5 定义测试类


监听器_设计模式_06


1.2.6 运行结果

监听器_设计模式_07


1.3 监听器设计模式

监听器设计模式,是观察者设计模式的一种实现,它并不是23种设计模式之一。

这里的监听器实际对应的就是观察者,而被监听对象,则是指被观察者。当被监听对象的状态发生改变时,也需通知监听器,监听器在收到通知后会做出相应改变。

与观察者设计模式不同的是,被监听者的状态改变,被定义为了一个对象,称为事件;被监听对象有了个新的名子,称为事件源;对监听器的通知,称为触发监听器。其实质与观察者设计模式是相同的。

下面以对被监听者所执行的增删改查CURD操作进行监听为例,来演示监听器设计模式的用法。

1.3.1 定义事件接口

一般情况下,监听器对象被事件触发后,都是需要从事件中获取到事件源对象,然后再从事件源中获取一些数据。也就是说,在事件对象中一般是需要提供获取事件源对象的方法的。当然,除了获取事件源的方法外,根据业务需求,事件对象一般还需要提供一些其它数据,以便让监听器获取。

监听器_IP_08


1.3.2 定义监听器接口

监听器_设计模式_09


1.3.3 定义事件源接口

监听器_监听器_10


1.3.4 定义事件类

监听器_监听器_11


1.3.5 定义监听器

监听器_IP_12


1.3.6 定义事件源

监听器_监听器_13


1.3.7 定义测试类

监听器_IP_14


1.3.8 运行结果

监听器_设计模式_15


1.3.9 再定义事件源

事件源是拥有自己的业务方法的,本例的业务方法为增删改查。应该是事件源对象在执行这些业务方法时触发监听器,而并非是前面测试类那么使用监听器。所以这里需要为事件源添加业务方法,在业务方法中触发监听器。

监听器_设计模式_16


1.3.10 再定义测试类

监听器_IP_17


第2章 监听器Listener

2.1 Servlet规范中的监听器

Servlet规范中已经定义好了八个监听器接口,它们要监听的对象分别是request、session、servletContext对象,触发监听器的事件是这三个对象的创建与销毁,它们的域属性空间中属性的添加、删除、修改,及session的钝化与活化操作。

在JavaWeb项目中使用监听器,需要在web.xml文件中对监听器进行注册。

监听器_监听器_18


下面分别对这八个监听器进行学习。

2.1.1 ServletRequestListener

该监听器用于完成对Request对象的创建及销毁的监听,即当Request对象被创建或被销毁时,会触发该监听器中相应方法的执行。

项目:requestListener

(1)定义并注册监听器

监听器_监听器_19


监听器_监听器_20


2.1.2 ServletRequestAttributeListener

该监听器用于完成对request域属性空间中属性的添加、修改、删除操作的监听。

项目:requestListener

(1)定义并注册监听器

注意ServletRequestAttributeEvent事件的方法getName()可以获取到被操作的属性名,方法getValue()可以获取到被操作的属性的值。

监听器_监听器_21


监听器_设计模式_22


(2)定义index.jsp页面

监听器_监听器_23


2.1.3 HttpSessionListener

该监听器用于完成对Session对象的创建及销毁的监听。

项目:sessionListener

(1)定义并注册监听器

监听器_IP_24


监听器_IP_25


(2)定义index.jsp页面

监听器_IP_26


2.1.4 HttpSessionAttributeListener

该监听器用于完成对session域属性空间中属性的添加、修改、删除操作的监听。

项目:sessionListener

(1)定义并注册监听器

监听器_设计模式_27


监听器_设计模式_28


(2)定义index.jsp页面

监听器_设计模式_29


2.1.5 ServletContextListener

该监听器用于完成对ServletContext对象的创建及销毁的监听。不过需要注意,由于ServletContext在一个应用中只有一个,且是在服务器启动时创建。另外,ServletConetxt的生命周期与整个应用的相同,所以当项目重新部署,或Tomcat正常关闭(通过stop service关闭,不能是terminate关闭)时,可以销毁ServletContext。

项目:servletContextListener

(1)定义并注册监听器

监听器_监听器_30


监听器_监听器_31


2.1.6 ServletContextAttributeListener

(1)定义并注册监听器

监听器_设计模式_32


监听器_IP_33


2定义index.jsp页面

监听器_IP_34


2.1.7 HttpSessionBindingListener

该监听器用于监听指定类型对象与Session的绑定与解绑,即该类型对象被放入到Session域中,或从Session域中删除该类型对象,均会引发该监听器中相应方法的执行。

它与HttpSessionAttributeListener的不同之处是,该监听器监听的是指定类型的对象在Session域中的操作,而HttpSessionAttributeListener监听的是 Session域属性空间的变化,无论是什么类型的对象。

另外,需要强调两点:①该监听器是由实体类实现;②该监听器无需在web.xml中注册。

项目:sessionBindingListener

(1)定义实现监听器接口的实体类

监听器_监听器_35


(2)定义index.jsp页面

监听器_IP_36


2.1.8 HttpSessionActivationListener

该监听器用于监听在Session中存放的指定类型对象的钝化与活化。

钝化是指将内存中的数据写入到硬盘中,而活化是指将硬盘中的数据恢复到内存。当用户正在访问的应用或该应用所在的服务器由于种种原因被停掉,然后在短时间内又重启,此时用户在访问时Session中的数据是不能丢掉的,在应用关闭之前,需要将数据写入到硬盘,在重启后应可以立即重新恢复Session中的数据。这就称为Session的钝化与活化。

那么Session中的哪些数据能够钝化呢?只有存放在JVM堆内存中的实现了Serializable类的对象能够被钝化。也就是说,对于字符串常量、基本数据类型常量等存放在JVM方法区中常量池中的常量,是无法被钝化的。

对于监听Session中对象数据的钝化与活化,需要注意以下几点:

● 实体类除了要实现HttpSessionActivationListener接口外,还需要实现Serializable接口。

● 钝化指的是Session中对象数据的钝化,并非是Session的钝化。所以Session中有几个可以钝化的对象,就会发生几次钝化。

● HttpSessionActivationListener监听器是不需要在web.xml中注册的。

(1)定义实现监听器接口的实体类

监听器_设计模式_37


(2)定义index.jsp页面

监听器_设计模式_38


(3)访问该项目

启动服务器后,在浏览器地址栏输入:http://localhost:8080/HttpSessionActivationListener/

监听器_监听器_39


然后正常关闭服务器,控制台输出

监听器_设计模式_40


当重新启动服务器时,控制台输出

监听器_监听器_41


2.2 监听器应用举例

2.2.1 在线客户端统计

统计连接在应用上的客户端数量。客户端的唯一标识就是IP,只需要将连接到服务器上的IP数量进行统计,就可统计出客户端的数量。这里需要注意一些细节: ● 从Request中可以获取到请求的IP,而从Session中是获取不到的。

● 从 Session 中是无法获取到Request对象的,因为session与request的关系是1:n,即一个会话中可以包含多个请求。

● 一个客户端可以发出很多请求与会话,但从这些请求中获取到的IP都是相同的。可以将获取到的IP放入到Map集合中,且以IP为key,可以保证集合中没有重复的IP。而value则为该IP的机器上所发出的会话对象所组成的List。

● 当一个客户端的Session被销毁时,应从map的当前ip所对应的value中,即List中删除当前的Session对象。然后再查看Map中该客户端IP所发出的会话List长度,若为0,则可将该IP所对应的Entry对象从Map中删除。

项目:clientCount

(1)定义ServletContext监听器

在ServletContext初始化时创建用于存放IP信息的Map集合,并将创建好的Map存放到ServletContext域中。

Map的key为客户端IP,而value则为该客户端ip所发出的会话对象组成的List。

监听器_设计模式_42


(2)定义Request监听器

Request监听器主要完成以下功能:

● 获取当前请求的客户端的IP。

● 获取当前IP所对应的全局域中的List。若这个List为空,则创建一个List。

● 将当前IP放入到List中,并将当前IP与List写入到Map中,然后再重新将Map写回ServletContext中。

● 将当前IP存放到当前请求所对应的Session域中,以备在Session销毁时使用。

监听器_设计模式_43


(3)定义Session监听器

该监听器的功能主要是,当Session被销毁时,将当前Session对象从List中删除。在从List删除后,若List中没有了元素,则说明这个IP所发出的会话已全部关闭,则可以将该IP所对应的Entry从map中删除了。若List中仍有元素,则将变化过的List重新再写入回map。

监听器_设计模式_44


  1. 注册监听器

监听器_监听器_45


(5)定义index.jsp页面

监听器_监听器_46


(6)定义并注册LogoutServlet

监听器_监听器_47


监听器_监听器_48


7)定义message.jsp页面

监听器_IP_49


2.2.2 管理员踢除用户

论坛管理员对于一些不守规矩的登录用户可以进行踢除。这里要完成的就是这个功能。这里有些细节需要注意:

● 什么是用户已经登录?就是用户信息写入到了Session中。

● 什么是对用户的踢除?就是使该用户信息所绑定的Session失效。

● 若要完成这个踢除功能,管理员首先应该可以看到所有在线用户。那么在线用户信息就应该保存在一个集合中。

● 这个集合既应该有用户信息,又应该有与用户信息绑定的Session对象。这样便于管理员获取到某一用户的Session后,将其失效。所以这个集合选用Map,key 为用户名(各站点都要求用户名是不能重复的,原因就是这个),value为与该用户绑定的Session。

● 这个Map集合中的数据应该在什么时候放进去?只要发生User对象与Session的绑定操作,就说明有用户登录。此时就应将数据放入到Map中。也就是说,应该为实体类User实现Session绑定监听器HttpSessionBindingListener。

● 这个Map集合应该什么时候创建?应该在应用启动时就创建,即在ServletConetxt被初始化时被创建。所以应该定义一个ServletContext监听器ServletContextListener,在ServletContext被初始化时创建这个Map集合。

项目:kickUsers

(1)定义用户登录页面index.jsp

监听器_设计模式_50


(2)定义实体类User

只要发生User对象与Session的绑定操作,就说明有用户登录。此时就应将数据放入到Map中。也就是说,实体类User应实现Session绑定监听器HttpSessionBindingListener。

监听器_监听器_51


(3)定义并注册ServletContext监听器

监听器_设计模式_52


监听器_设计模式_53


4)定义并注册LoginServlet

用户提交登录表单后,马上与Session进行绑定,以便将信息写入到Map中。

监听器_IP_54


监听器_IP_55


5)定义welcome.jsp页面

监听器_设计模式_56


6)定义用户列表页面userList.jsp

这其中用到了显示序号、隔行着色。而这些功能的完成,是由的varStatus属性配合着完成的。

监听器_监听器_57


7)定义并注册DeleteServlet

这里需要注意的是,当将当前user的Session失效后,还需要将当前user对应的Entry对象从Map中删除,否则,userList页面的列表中仍然会显示这个用户。因为Map仍存在,只不过该session失效而已。

将指定用户踢除后,重新返回到userList页面,显示更新过的列表。

监听器_IP_58


监听器_IP_59










标签:定义,对象,观察者,Session,监听器,设计模式
From: https://blog.51cto.com/u_16230968/7908716

相关文章

  • Spring Boot中的过滤器、拦截器、监听器技巧汇总:让你快速成为大神
    ......
  • 实现点赞功能-实现点赞数变更的消息监听器
        ......
  • Oracle数据库同时建立和使用两个监听器
    1.问题我分别对两个数据库实例(Lib和Orcl)各自建立了一个监听器,端口号分别为1520和1521,但是默认只启动一个,导致我切换数据库实例的时候,出现以下问题:状态:失败-测试失败:IO错误:TheNetworkAdaptercouldnotestablishtheconnection(CONNECTION_ID=eWHa4AMrRfy8g/bXkm9lw......
  • 过滤器| 拦截器| 监听器的区别与使用
    骑士李四记录:1.过滤器(Filter):过滤器依赖于servlet容器。在实现上基于函数回调。几乎可以对所有请求进行过滤。缺点是一个过滤器实例只能在容器初始化时调用一次。2.拦截器(Interceptor)拦截器依赖于web框架,在SpringMVC中依赖于SpringMVC框架。实现上基于java反射机制,属于面向切......
  • 1、oracle监听器服务的开启与关闭
    目录oracle监听器服务的开启与关闭1、查看监听状态2、开启监听3、关闭监听4、重启监听oracle监听器服务的开启与关闭Oracle监听器服务关闭时,不让外部进行数据库连接。1、查看监听状态lsnrctlstatus2、开启监听lsnrctlstart3、关闭监听lsnrctlstop4、重启监听lsnrc......
  • 老杜 JavaWeb 讲解(二十) ——Listener监听器
    (十八)Listener监听器引子:静态代码块packagecom.zwm.javaweb.servlet;/***@author猪无名*@date2023/8/81347*discription:*/publicclasstest2{//静态代码块在类加载时执行,并且只执行一次。//这个语法很简单,但什么时候用?很疑惑//假如,你希......
  • EAS_客户端监听器
    1.文本控件监听(KDTextField)例如有文本控件:privateKDTextFieldtxtBillPackageNo; 对于文本监听器,不像其他控件可以直接 txtBillPackageNo.addxxxx来添加监听,我们可以通过不同的方法来实现,有以下几种第一种:通过监听鼠标的操作来实现监听,再对应的方法中添加自己想要处理......
  • MVC三层架构,过滤器、监听器及常见应用
    MVC三层架构什么是MVC:ModelViewController模型、视图、控制器10.1早些年控制器ControllerServlet:接收用户的请求响应给客户端内容重定向或者转发视图层ViewJSP:展示数据提供可以供我们操作的请求Servlet和JSP都可以写JAVA代码;为了易于维护和使用;Servlet专注于......
  • Spring高手之路7——事件机制与监听器的全面探索
    1.Spring中的观察者模式  观察者模式是一种行为设计模式,它定义了对象之间的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。在这个模式中,改变状态的对象被称为主题,依赖的对象被称为观察者。举个实际的例子:事件源(EventSource):可以视为“主题(Sub......
  • spring 监听器 IntrospectorCleanupListener简介
     spring中的提供了一个名为org.springframework.web.util.IntrospectorCleanupListener的监听器。它主要负责处理由JavaBeans Introspector的使用而引起的缓冲泄露。spring中对它的描述如下: 它是一个在web应用关闭的时候,清除JavaBeansIntrospector的监听器.在web.xml中......