一.介绍
(1)监听器接口是一组来自于Servlet规范下接口,共有8个接口。在Tomcat存在servlet-api.jar包
(2)监听器接口需要由开发人员亲自实现,Http服务器提供jar包,但是并没有对应的实现类
(3)监听器接口用于监控【作用域对象生命周期变化时刻】以及【作用域对象共享数据变化时刻】
二.什么是作用域对象?
1)在Servlet规范中,认为在服务端内存中可以在某些条件下为两个Servlet之间提供数据共享方案的对象,被称为【作用域,对象】
2)Servlet规范下作用域对象:一共有三个。注意是没有cookie的,因为cookie出身不好,是因为其存储在客户端的浏览器缓存中,并不在服务端。
ServletContext: 全局作用域对象 HttpSession : 会话作用域对象 HttpServletRequest:请求作用域对象
三.监听器接口实现类开发规范
这里面一共分为了三步:
1)根据监听的实际情况,选择对应监听器接口进行实现, 例如看到底是想监听全局作用域对象的生命周期变化时刻,还是会话作用域对象的共享数据变化时刻,然后再从八个接口中选出来对应的接口来实现。 2)重写监听器接口中所声明的【监听事件处理方法】,这些方法会在指定事件发生的时候自动调用,你只需要告诉这些方法在调用的时候要干嘛,不需要去考虑太是什么时候调用的。 3)在web.xml文件将监听器接口实现类注册到Http服务器
四.代码示例
此处的代码示例我们就拿ServletContext接口来举例,分别介绍关于这个接口的两个监听器方法:一个是ServletContextListener接口,一个是ServletContextAttributeListener接口
1.ServletContextListener接口(8个接口之一)
(1)作用
通过这个接口合法的检测全局作用域对象被初始化时刻以及被销毁时刻
(2)监听事件处理方法
也就是ServletContextListener接口中所定义的两个方法:
public void contextInitlized() 在全局作用域对象被Http服务器初始化被调用 public void contextDestory(): 在全局作用域对象被Http服务器销毁时候触发调用
(3)代码示例
第一步:确定了我们是想监听ServletContext接口所修饰的对象,也就是我们全局作用域对象何时被创建,何时被销毁,所以此时应该实现我们的ServeltContextListener接口。
第二步:我们此时定义一个监听类名为OneListener去实现我们的ServeltContextListener接口,重写接口中的两个方法:代码如下所示:
public class OneListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("全局作用域对象被创建了"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("全局作用域对象被销毁了"); } }
可以看到我们在重写的方法中加入输出语句,方便待会我们观察全局作用域对象的创建销毁时间。
第三步:将我们的监听器接口实现类注册到我们的http服务器当中去:此时需要去web.xml文件中配置如下语句:
<listener> <listener-class>com.bjpowernode.listener.OneListener</listener-class> </listener>
注意class里面放入的是我们监听器接口实现类的地址的全限定名称 。
从之前的概念中我们得知我们全局作用域对象的声明周期为:
(1)在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象
(2)在Http服务器运行期间时,一个网站只有一个全局作用域对象
(3)在Http服务器运行期间,全局作用域对象一直处于存活状态
(4)在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理
所以当我们启动tomcat的时候,我们的OneListener类中的contextInitialized方法此时便开始执行了,那么此时应该输出"全局作用域对象被创建了"这句话,如图所示:
当我们关闭tomcat的时候,我们的OneListener类中的contextDestroyed方法此时便开始执行了,那么此时应该输出"全局作用域对象被销毁了"这句话,如图所示:
2.ServletContextAttributeListener接口
1.作用
通过这个接口合法的检测全局作用域对象共享数据变化时刻
2.监听事件处理方法
也就是ServletContextListener接口中所定义的三个方法:
public void contextAdd(): 在全局作用域对象添加共享数据时调用此方法 public void contextReplaced():在全局作用域对象更新共享数据调用此方法 public void contextRemove(): 在全局作用域对象删除共享数据时调用此方法
3.全局作用域对象添加,更新,删除共享数据的方法
ServletContext application = request.getServletContext(); application.setAttribute("key1",100); //新增共享数据 application.setAttribute("key1",200); //更新共享数据 application.removeAttribute("key1"); //删除共享数据
4.代码示例
第一步:确定了我们是想监听ServletContext接口所修饰的对象,也就是我们全局作用域对象的数据何时添加,何时被更新,何时被删除,所以此时应该实现我们的ServletContextAttributeListener接口
第二步:我们此时定义一个监听类名为OneListener去实现我们的ServletContextAttributeListener接口,重写接口中的三个方法:代码如下所示:
public class OneListener implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent scae) { System.out.println("新增共享数据"); } @Override public void attributeRemoved(ServletContextAttributeEvent scae) { System.out.println("删除共享数据"); } @Override public void attributeReplaced(ServletContextAttributeEvent scae) { System.out.println("更新共享数据"); } }
此时我们在重写的方法中分别放入我们的业务逻辑,此处为了方便记录我们的全局作用域对象中的数据的变化情况,我们就分别写入不同的输出语句,在控制台观察数据变化时语句的输出顺序,从而通过语句的输出顺序便可以判断出全局作用域对象中数据都发生了什么变化。
下面我们继续去编写我们的controller包下的OneServlet类,这个类的作用就是为了执行我们全局作用域对象数据的添加,更新,删除操作。
public class OneServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext application = request.getServletContext(); application.setAttribute("key1",100); //新增共享数据 application.setAttribute("key1",200); //更新共享数据 application.removeAttribute("key1"); //删除共享数据 } }
执行完操作后,此时我们执行我们的项目,按照上述截图对于数据操作的编写情况,我们最终监听完成后的输出语句的顺序应该为
第一次执行setAttribute方法-------------------------》监听器此时监听到了全局作用域对象中数据的添加操作,然后会调用我们的attributeAdded方法,所以首先输出的语句为“新增共享数据” 第二次执行setAttribute方法-------------------------》监听器此时监听到了全局作用域对象中数据的更新操作,然后会调用我们的attributeReplaced方法,所以其次输出的语句为“更新共享数据” 最后执行removeAttribute方法----------------------》监听器此时监听到了全局作用域对象中数据的删除操作,然后会调用我们的attributeRemoved方法,所以最终输出的语句为“删除共享数据”
所以最终的输出结果如下所示: