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的监听接口,实现其启动和销毁时要执行的方法:
public class VisitCountsListener implements ServletContextListener { 

    /**
* 容器启动时
* @param sce
*/
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
String path = context.getRealPath("/WEB-INF/temp/visit.txt");
File file = new File(path);
int count = 0; try {
if (file.exists()) {
BufferedReader reader = new BufferedReader(new FileReader(path));
count = Integer.valueOf(reader.readLine());
}
} catch (IOException e) {
e.printStackTrace();
} context.setAttribute("count", count);
} /**
* 容器关闭时
* @param sce
*/
public void contextDestroyed(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
String path = context.getRealPath("/WEB-INF/temp/visit.txt");
File file = new File(path); try {
if (file.exists()) {
file.delete();
}
file.createNewFile(); BufferedWriter writer = new BufferedWriter(new FileWriter(file));
writer.write(context.getAttribute("count").toString());
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
x
 
1
public class VisitCountsListener implements ServletContextListener { 
2

3
    /**
4
     * 容器启动时
5
     * @param sce
6
     */
7
    public void contextInitialized(ServletContextEvent sce) {
8
        ServletContext context = sce.getServletContext();
9
        String path = context.getRealPath("/WEB-INF/temp/visit.txt");
10
        File file = new File(path);
11
        int count = 0;
12

13
        try {
14
            if (file.exists()) {
15
                BufferedReader reader = new BufferedReader(new FileReader(path));
16
                count = Integer.valueOf(reader.readLine());
17
            }
18
        } catch (IOException e) {
19
            e.printStackTrace();
20
        }
21

22
        context.setAttribute("count", count);
23
    }
24

25
    /**
26
     * 容器关闭时
27
     * @param sce
28
     */
29
    public void contextDestroyed(ServletContextEvent sce) {
30
        ServletContext context = sce.getServletContext();
31
        String path = context.getRealPath("/WEB-INF/temp/visit.txt");
32
        File file = new File(path);
33

34
        try {
35
            if (file.exists()) {
36
                file.delete();
37
            }
38
            file.createNewFile();
39

40
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
41
            writer.write(context.getAttribute("count").toString());
42
            writer.flush();
43
            writer.close();
44
        } catch (IOException e) {
45
            e.printStackTrace();
46
        }
47
    }
48
}

4.2 在web.xml中配置监听器

<listener>
<listener-class>com.zker.VisitCountsListener</listener-class>
</listener>
 
1
<listener>
2
    <listener-class>com.zker.VisitCountsListener</listener-class>
3
</listener>


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

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

    监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用 一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听 ...

  2. javaWeb学习总结(11)- 监听器(Listener)在开发中的应用

    监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用 一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听 ...

  3. javaWeb学习总结(11)- 监听器(Listener)学习

    一.监听器介绍 1.1.监听器的概念 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其 实就是一个实现特定接口的普 ...

  4. java之Servlet监听器Listener

    常用应用场景:单点登录.统计在线人数 一.简介 (一)概述 1.Listener 用于监听 java web程序中的事件,例如创建.修改.删除Session.request.context等,并触发响 ...

  5. 过滤器Filter与监听器Listener

    过滤器Filter 过滤器也是一种servlet   它也可以对用户的请求进行处理  , 但是他所做的处理,只是一些轻量级的处理.Fileter就好像jsp页面与servlet之间的一道关卡,如果这个 ...

  6. JAVA监听器Listener

    JAVA监听器Listener 一. 简介 监听器用于对web中内置对象的状态或者属性变化进行监听并做出相应响应的一种Servlet;在内置对象的生命周期中,产生.销毁等状态发生变化时,监听器就会进行 ...

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

    一.Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servle ...

  8. JavaWeb学习 (二十七)————监听器(Listener)在开发中的应用

    监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用 一.统计当前在线人数 在JavaWeb应用开发中,有时候我们需要统计当前在线的用户数,此时就可以使用监听 ...

  9. Servlet 监听器Listener详解

    转自:http://blog.csdn.net/u012228718/article/details/41730799 一.简介 (一)概述 1.Listener 用于监听 Javaweb程序中的事件 ...

随机推荐

  1. cat命令汇总整理

    Cat命令:一般用作打开文件,查看文件内容(可以一次查看多个文件),参数有如下几个: -a 或 –all,显示全部 -b 或--number-nonblank 对非空输出行编号 -n 或 --numb ...

  2. async简单使用

    node的异步io虽然好用,但是控制异步流程确实一个比较麻烦的事情,比如在爬虫中控制并发数量,避免并发过大导致网站宕机或被加入黑名单.因此需要一个工具来控制并发,这个工具可以自己写或者使用async( ...

  3. android studio 2.3 编译动态库

    工作需要编译android下的动态库,本以为是一件简单的事,没想到因为工具,以及google本身被墙的原因,折腾了好久. 在windows外的平台搞事情,寿命都得缩短. 一种方案是用eclipse+n ...

  4. ID3算法(2)

    今天,我来讲解的是决策树.对于决策树来说,主要有两种算法:ID3算法和C4.5算法.C4.5算法是 对ID3算法的改进.今天主要先讲ID3算法,之后会讲C4.5算法和随机森林等. Contents   ...

  5. linux下FTP服务器搭建教程1

    你买了个主机就像是买了块地皮,搭建FTP就像是盖房子,我在地皮上建房子,然后创建的用户就像是钥匙,我给谁钥匙(权限),谁就可以到我家去玩,去放东西,拿东西. 虽然我们买不起现实的房子,但是我们可以买互 ...

  6. Thinkjs使用ajax实现表单提交

    //前端代码 1 $('form').submit(evt=>{ evt.preventDefault();//阻止表单默认提交 $.ajax({ url: '/user/personal/up ...

  7. node.js 下载安装及gitbook环境安装、搭建

    最近需要gitbook看文档,于是各种百度,各种安装,很多都是无法正常安装完成的,比较纠结啊 最后,终于发现一个好用的,现分享一下地址(也是给自己做个记录): 1.node.js下载地址: http: ...

  8. ajax请求后台,有时收不到返回值的解决办法

    昨天下午做项目遇到一个问题,贴出来方便以后翻阅,也给大家个参考. 问题: 具体做的是个文件导入的功能,导入的功能是成功了,但是界面一直得不到返回值,排查了一下午,调试的时候是可以有返回的,但是关掉浏览 ...

  9. 第1阶段——uboot分析之查找命令run_command函数和命令定义过程(6)

    本节主要学习,run_command函数命令查找过程,命令生成过程 1.run_command函数命令查找过程分析:在u-boot界面中(main_loop();位于u-boot-1.1.6/comm ...

  10. JSONP的实现流程

    在进行AJAX的时候会经常产生这样一个报错: 看红字,这是浏览器的同源策略,使跨域进行的AJAX无效.注意,不是不发送AJAX请求(其实就是HTTP请求),而是请求了,也返回了,但浏览器‘咔擦’一声, ...