[09] 监听器 Listener

1、事件

1.1 事件的概念

在Servlet中有一个概念叫做监听,顾名思义,就是监听某种事件是否发生。就如你是一家娱乐媒体公司的老板,你派出狗仔队去跟着某些明星,比如你想了解他们的绯闻,或者活动进展情况。这里的绯闻和活动进展情况,就是所谓的事件。

在Web编程中,某些操作总会触发一种事件的发生,如启动或关闭容器、创建和销毁对话等。我们说过,Java是面向对象的语言,所以当发生了某种事件,容器将会创建对应的事件类对象。

也就是说,API中已经定义好了事件的类型,容器进行了实现,当某些特定操作发生时,会自动触发相应的事件。

1.2 事件类型

Servlet API中定义了6种事件类型:

  • ServletContextEvent
  • 该类表示上下文事件,当应用上下文对象发生改变,如创建或销毁上下文对象时,将触发上下文事件
  • ServletContextAttributeEvent
  • 该类表示上下文属性事件,当应用上下文的属性发生变化,如增加、删除、覆盖上下文中的属性时,将触发该事件
  • ServletRequestEvent
  • 该类表示请求事件,当请求对象发生改变,如创建或销毁请求对象时,触发请求事件
  • ServletRequestAttributeEvent
  • 该类表示请求属性事件,当请求中的属性发生改变,如增加、删除、覆盖请求中的属性时,触发请求属性事件
  • HttpSessionEvent
  • 该类表示会话事件,当会话对象发生改变,如创建或销毁会话对象,活化或钝化会话对象时,将触发会话事件
  • HttpSessionBindingEvent
  • 该类表示会话绑定事件,当会话中的属性发生变化时,如增加、删除、覆盖会话中的属性时,将触发会话绑定事件

2、监听器

每一个事件类型都有一个接口去监听,这就是监听器。就像我派狗仔A负责绯闻部分,狗仔B负责活动进展部分。

Servlet API中定义了8种监听器接口,用来监听不同的事件类型:

  • ServletContextListener
  • 上下文监听器,监听ServletContextEvent事件
  • ServletContextAttributeListener
  • 上下文属性监听器,用来监听ServletContextAttribute事件
  • ServletRequestListener
  • 请求监听器,监听ServletRequestEvent事件
  • ServletRequestAttributeListener
  • 请求属性监听器,用来监听ServletRequestAttributeEvent事件
  • HttpSessionListener
  • 会话监听器,监听HttpSessionEvent事件
  • HttpSessionActivationListener
  • 会话活化监听器,监听HttpSessionEvent事件
  • HttpSessionAttributeListener
  • 会话属性监听器,监听HttpSessionAttributeEvent事件
  • HttpSessionBindingListener
  • 会话绑定监听器,监听HttpSessionAttributeEvent事件

在会话相关的事件类型和监听器中,都提到了两个字眼:“活化” 和 “钝化”。这是容器为了提高资源的使用,对会话的一种机制,而且不同的容器(服务器)对它的实现是不一样的,所以比较难以直接测试进行复现。

所谓钝化,就是会话对象还没有超时,但是确实已经活动得比较少了,那么这时就把它从内存放到外存上;当后来它又被使用了,那么又将其取回来,这个叫活化。简单地说,从内到外叫钝化;从外到内叫活化。

3、事件和监听的关系

事件对象是容器创建的,触发的条件也已经定义好。例如,只要容器关闭或启动,就会触发ServletContextEvent事件,容器会创建该类型的对象。

当事件发生后,容器会寻找监听器来处理该事件。监听器需要程序员自定义并配置,然而监听器的类型已经定义好了。例如,当发生了ServletContextEvent事件后,只能使用ServletContextListener监听器来监听。

而我们要做的事,就是要把监听器中的方法进行实现,用来做我们想做的事情。

4、示例:用监听器修改登录计数器

我们有一个计数器,存储在上下文对象中,每次用户登录时就将该计数器数字增加,但是当容器重启,或应用重新部署后,上下文对象将重新创建,所以计数又从1开始,这显然出现了数据丢失。

我们现在的目标,就是利用文本文件对数据进行存储:

  • 当容器关闭时,把当前数值保存到文本文件中
  • 当容器启动时,从文本文件中读取数值。

显然,我们可以用监听器来监听容器的启动和关闭情况:

4.1 写一个监听器

自定义一个监听器类,并实现ServletContextListener的监听接口,实现其启动和销毁时要执行的方法:

  1. public class VisitCountsListener implements ServletContextListener {
  2. /**
  3. * 容器启动时
  4. * @param sce
  5. */
  6. public void contextInitialized(ServletContextEvent sce) {
  7. ServletContext context = sce.getServletContext();
  8. String path = context.getRealPath("/WEB-INF/temp/visit.txt");
  9. File file = new File(path);
  10. int count = 0;
  11. try {
  12. if (file.exists()) {
  13. BufferedReader reader = new BufferedReader(new FileReader(path));
  14. count = Integer.valueOf(reader.readLine());
  15. }
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. context.setAttribute("count", count);
  20. }
  21. /**
  22. * 容器关闭时
  23. * @param sce
  24. */
  25. public void contextDestroyed(ServletContextEvent sce) {
  26. ServletContext context = sce.getServletContext();
  27. String path = context.getRealPath("/WEB-INF/temp/visit.txt");
  28. File file = new File(path);
  29. try {
  30. if (file.exists()) {
  31. file.delete();
  32. }
  33. file.createNewFile();
  34. BufferedWriter writer = new BufferedWriter(new FileWriter(file));
  35. writer.write(context.getAttribute("count").toString());
  36. writer.flush();
  37. writer.close();
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }

4.2 在web.xml中配置监听器

  1. <listener>
  2. <listener-class>com.zker.VisitCountsListener</listener-class>
  3. </listener>
时间: 2024-08-29 03:01:46

[09] 监听器 Listener的相关文章

javaweb学习总结(四十七)——监听器(Listener)在开发中的应用

监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用 一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听器技术来实现这个功能了. 1 package me.gacl.web.listener; 2 3 import javax.servlet.ServletContext; 4 import javax.servlet.http.HttpSessionEvent; 5 import javax.ser

servlet监听器Listener(理论+例子)

Listener采用了观察者模式(24种模式之一),Listener是servlet的监听器,他可以监听客户端的请求.服务器端的操作等, 通过监听器,可以自动激发一些操作.比如:监听在线用户数量 当增加一个HttpSession时,就会激发sessinCreated(HttpSessionEvent sce)方法,这样就可以给在线人数+1了. 常见的监听器接口: ServletContextAttributeListener 监听对servletContext属性的操作,比如删除.增加.修改属性

JavaWeb开发——servlet监听器 listener

一.Servlet监听器的概念 Servlet监听器是Servlet规范中定义的一种特殊类,用于监听ServletContext.HttpSession和ServletRequest等域对象的创建与销毁事件, 以及监听这些域对象中属性发生修改的事件. 监听对象: 1.ServletContext:application,整个应用只存在一个 2.HttpSession:session,针对每一个对话 3.ServletRequest:request,针对每一个客户请求 监听内容:创建.销毁.属性改

Javaweb基础---&gt;监听器listener(转发)

JavaWeb中的监听器 1.基本概念 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件. 2.Servlet监听器的分类 在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为ServletContext,HttpSession和ServletRequest这三个域对象 Servle

Servlet3.0学习总结(四)——使用注解标注监听器(Listener)

Servlet3.0学习总结(四)——使用注解标注监听器(Listener) Servlet3.0提供@WebListener注解将一个实现了特定监听器接口的类定义为监听器,这样我们在web应用中使用监听器时,也不再需要在web.xml文件中配置监听器的相关描述信息了. 下面我们来创建一个监听器,体验一下使用@WebListener注解标注监听器,如下所示: 监听器的代码如下: 1 package me.gacl.web.listener; 2 3 import javax.servlet.Se

Oracle故障排除—Oracle监听器listener不认数据库

1.启动Oracle数据库监听器执行su –oracle lsnrctl start后,执行lsnrctl status查看当前监听器状态,发现: 说明数据库的listener监听器已经启动起来了.但是没有显示Instance "LINXI", status READY,说明数据库监听器没有认到数据库. 2.具体处理办法就是重新注册一下,方法如图: 3.然后重新进行数据库监听器listener状态查询,显示:显示Instance "LINXI", status RE

Servlet监听器Listener

Listener实在servlet2.3中加入的,主要用于对Session,request,context等进行监控. 使用Listener需要实现响应的接口.触发Listener事件的时候,tomcat会自动调用Listener的方法. 在web.xml中配置标签,一般要配置在<servlet>标签前面,可配置多个,同一种类型也可配置多个 <listener> <listener-class>com.xxx.xxx.ImplementListener</list

过滤器(Filter)、拦截器(Interceptor)、监听器(Listener)

一.Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能.例如实现URL级别的权限访问控制.过滤敏感词汇.压缩响应信息等一些高级功能. 它主要用于对用户请求进行预处理,也可以对HttpServletResponse 进行后处理.使用Filter 的完整流程:Filter 对用户请求

JavaWeb-18 (JDBC之分页与监听器listener)

JavaWeb-18 JDBC之分页与监听器listener 一.分页 1.分页概述:分页的结果就是要让指定的记录加载到内存 2.原因: 1.人的习惯 2.内存的限度(核心问题) 3.屏幕的限度 3.如何分页: 不同的环境方式不一样 3.1.数据库层面: select * from acount limit startIndex,size;//只是针对MySql而言(startIndex从0开始,size:共查询多少条记录) select * from acount limit 0,3; 第一页