一、监听器介绍

1.1、监听器的概念

  监听器是一个专门用于对其它对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监听的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听的对象发生上述事件就,监听器的某个方法立即被执行。

1.2、设计一个可以被别的对象监听的对象

  我们平时做开发的时候,我们是写监听器去监听其他对象,那么我们如果想设计一个对象,让这个对象可以被别的对象监听又该怎么做呢,可以按照严格的事件处理模型来设计一个对象,这个对象就可以被别的对象监听,事件处理模型涉及到三个组件:事件源、事件对象、事件监听器。

  下面我们来按照事件处理模型来设计一个Person对象,具体代码如下:

 package me.gacl.observer;

 /**
* @ClassName: Person(事件源)
* @Description: 设计一个Person类作为事件源,这个类的对象的行为(比如吃饭、跑步)可以被其他的对象监听
* @author: 孤傲苍狼
* @date: 2014-9-9 下午9:26:06
*
*/
public class Person {
/**
* @Field: listener
* 在Person类中定义一个PersonListener变量来记住传递进来的监听器
*/
private PersonListener listener; /**
* @Method: eat
* @Description: 设计Person的行为:吃
* @Anthor:孤傲苍狼
*
*/
public void eat() {
if (listener != null) {
/**
* 调用监听器的doeat方法监听Person类对象eat(吃)这个动作,将事件对象Event传递给doeat方法,
* 事件对象封装了事件源,new Event(this)中的this代表的就是事件源
*/
listener.doeat(new Event(this));
}
} /**
* @Method: run
* @Description: 设计Person的行为:跑
* @Anthor:孤傲苍狼
*
*/
public void run() {
if (listener != null) {
/**
* 调用监听器的dorun方法监听Person类对象run(跑)这个动作,将事件对象Event传递给doeat方法,
* 事件对象封装了事件源,new Event(this)中的this代表的就是事件源
*/
listener.dorun(new Event(this));
}
} /**
* @Method: registerListener
* @Description: 这个方法是用来注册对Person类对象的行为进行监听的监听器
* @Anthor:孤傲苍狼
*
* @param listener
*/
public void registerListener(PersonListener listener) {
this.listener = listener;
}
} /**
* @ClassName: PersonListener(事件监听器)
* @Description: 设计Person类(事件源)的监听器接口
* @author: 孤傲苍狼
* @date: 2014-9-9 下午9:28:06
*
*/
interface PersonListener { /**
* @Method: doeat
* @Description: 这个方法是用来监听Person对象eat(吃)这个行为动作,
* 当实现类实现doeat方法时就可以监听到Person类对象eat(吃)这个动作
* @Anthor:孤傲苍狼
*
* @param e
*/
void doeat(Event e); /**
* @Method: dorun
* @Description: 这个方法是用来监听Person对象run(跑)这个行为动作,
* 当实现类实现dorun方法时就可以监听到Person类对象run(跑)这个动作
* @Anthor:孤傲苍狼
*
* @param e
*/
void dorun(Event e); } /**
* @ClassName: Event(事件对象)
* @Description:设计事件类,用来封装事件源
* @author: 孤傲苍狼
* @date: 2014-9-9 下午9:37:56
*
*/
class Event { /**
* @Field: source
* 事件源(Person就是事件源)
*/
private Person source; public Event() { } public Event(Person source) {
this.source = source;
} public Person getSource() {
return source;
} public void setSource(Person source) {
this.source = source;
}
}

  经过这样的设计之后,person类的对象就可以被其它对象监听了。测试代码如下:

 package me.gacl.observer;

 public class PersonTest {

     /**
* @Method: main
* @Description: 测试Person类
* @Anthor:孤傲苍狼
*
* @param args
*/
public static void main(String[] args) {
//
Person p = new Person();
//注册监听p对象行为的监听器
p.registerListener(new PersonListener() {
//监听p吃东西这个行为
public void doeat(Event e) {
Person p = e.getSource();
System.out.println(p + "在吃东西");
}
//监听p跑步这个行为
public void dorun(Event e) {
Person p = e.getSource();
System.out.println(p + "在跑步");
}
});
//p在吃东西
p.eat();
//p在跑步
p.run();
}
}

  运行结果:

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)编写监听器,代码如下:

 package me.gacl.web.listener;

 import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; /**
* @ClassName: MyServletContextListener
* @Description: MyServletContextListener类实现了ServletContextListener接口,
* 因此可以对ServletContext对象的创建和销毁这两个动作进行监听。
* @author: 孤傲苍狼
* @date: 2014-9-9 下午10:26:16
*
*/
public class MyServletContextListener implements ServletContextListener { @Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象创建");
} @Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象销毁");
}
}

  (2)在web.xml文件中注册监听器

  我们在上面讲到,要想监听事件源,那么必须将监听器注册到事件源上才能够实现对事件源的行为动作进行监听,在JavaWeb中,监听的注册是在web.xml文件中进行配置的,如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> <!-- 注册针对ServletContext对象进行监听的监听器 -->
<listener>
<description>ServletContextListener监听器</description>
<!--实现了ServletContextListener接口的监听器类 -->
<listener-class>me.gacl.web.listener.MyServletContextListener</listener-class>
</listener> </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)编写监听器,代码如下:

 package me.gacl.web.listener;

 import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; /**
* @ClassName: MyHttpSessionListener
* @Description: MyHttpSessionListener类实现了HttpSessionListener接口,
* 因此可以对HttpSession对象的创建和销毁这两个动作进行监听。
* @author: 孤傲苍狼
* @date: 2014-9-9 下午11:04:33
*
*/
public class MyHttpSessionListener implements HttpSessionListener { @Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println( se.getSession() + "创建了!!");
System.out.println("创建好的HttpSession的id是:" + se.getSession().getId());
} /* HttpSession的销毁时机需要在web.xml中进行配置,如下:
* <session-config>
<session-timeout>1</session-timeout>
</session-config>
这样配置就表示session在1分钟之后就被销毁
*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session销毁了!!");
}
}

  (2)web.xml文件中注册监听器

<!--注册针对HttpSession对象进行监听的监听器-->
<listener>
<description>HttpSessionListener监听器</description>
<listener-class>me.gacl.web.listener.MyHttpSessionListener</listener-class>
</listener>
<!-- 配置HttpSession对象的销毁时机 -->
<session-config>
<!--配置HttpSession对象的1分钟之后销毁 -->
<session-timeout>1</session-timeout>
</session-config>

  当我们访问jsp页面时,HttpSession对象就会创建,此时就可以对HttpSessionListener观察到HttpSession对象的创建过程了。

  运行结果如下:

2.5、监听ServletRequest域对象的创建和销毁

  ServletRequestListener接口用于监听ServletRequest对象的创建和销毁

  Request对象被创建时,监听器的requestInitialized(ServletRequestEvent sre)方法将会被调用

  Request对象被销毁时,监听器的requestDestroyed(ServletRequestEvent sre)方法将会被调用

  ServletRequest域对象创建和销毁时机:
    创建:用户每一次访问都会创建request对象
    销毁:当前访问结束,request对象就会销毁

范例:编写一个MyServletRequestListener类,实现ServletRequestListener接口,监听ServletRequest对象的创建和销毁

  (1)编写监听器,代码如下:

 package me.gacl.web.listener;

 import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener; /**
* @ClassName: MyServletRequestListener
* @Description: MyServletRequestListener类实现了ServletRequestListener接口,
* 因此可以对ServletRequest对象的创建和销毁这两个动作进行监听。
* @author: 孤傲苍狼
* @date: 2014-9-9 下午11:50:08
*
*/
public class MyServletRequestListener implements ServletRequestListener { @Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println(sre.getServletRequest() + "销毁了!!"); } @Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println(sre.getServletRequest() + "创建了!!");
}
}

  (2)在web.xml文件中注册监听器

<!--注册针对ServletRequest对象进行监听的监听器-->
<listener>
<description>ServletRequestListener监听器</description>
<listener-class>me.gacl.web.listener.MyServletRequestListener</listener-class>
</listener>

  测试结果如下:

  从运行结果中可以看到,用户每一次请求都会创建request对象,当请求结束后,request对象就会销毁。

  转载自《javaWeb学习总结(11)- 监听器(Listener)学习

【转】监听器(Listener)学习的更多相关文章

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

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

  2. 监听器(Listener)学习(二)在开发中的常见应用

    监听器在JavaWeb开发中用得比较多,下面说一下监听器(Listener)在开发中的常见应用: 统计当前在线人数 自定义Session扫描器 一.统计当前在线人数 在JavaWeb应用开发中,有时候 ...

  3. 监听器(Listener)学习(二)

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

  4. 监听器(Listener)学习(一)

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

  5. 深入分析JavaWeb Item39 -- 监听器(Listener)学习进阶

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

  6. javaweb学习总结(四十五)——监听器(Listener)学习二

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

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

    一.监听器介绍 1.1.监听器的概念

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

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

  9. JavaWeb学习 (二十六)————监听器(Listener)学习(二)

    一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...

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

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

随机推荐

  1. (light oj 1102) Problem Makes Problem (组合数 + 乘法逆元)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1102 As I am fond of making easier problems, ...

  2. Vue中循环的反人类设计

    今天学习Vue到循环那里,表示真是不能理解Vue的反人类设计 具体看代码吧! <!DOCTYPE html> <html> <head> <meta char ...

  3. SSM项目使用GoEasy 获取客户端上下线实时状态变化及在线客户列表

    一.背景 上篇SSM项目使用GoEasy 实现web消息推送服务是GoEasy的一个用途,今天我们来看GoEasy的第二个用途:订阅客户端上下线实时状态变化.获取当前在线客户数量和在线客户列表.截止我 ...

  4. Vue中的状态管理器 - Vuex

    我们知道vue是组件式开发的,当你的项目越来越大后,每个组件背后的数据也会变得越来越难以理顺, 这个时候你就可以考虑使用vuex了. 备注: 官方建议小项目不要使用,引入vuex会带来新的概念和模式, ...

  5. call, apply 和 bind 方法

    我们知道,每个函数在调用的时候会产生一个执行上下文环境,而这个执行上下文环境中包含了诸如 this 等等信息.即当我们调用函数的时候,内部的 this 已经明确地隐式绑定到了某一个对象上.如果我们希望 ...

  6. pointer-events: none

    如果为某个元素样式设置了“pointer-events: none ”,事件.连接.悬浮样式都没有了 如果为a标签设置了“pointer-events: none ”,点击a标签,不会跳转到链接地址, ...

  7. MarkDown&思维导图

    从markdown文件创建思维导图 pzhaonet/mindr: an R package which converts markdown files (.md, .Rmd) into mindma ...

  8. [洛谷P1006] 传纸条

    双线程DP的常识:DP的阶段问题:多阶段决策问题 传送门:$>here<$ 题意 n*m的矩阵里,从左上角走到右下角(只能往右或往下),再从右下角走回左上角(只能往左或往上).其中不能重复 ...

  9. python学习日记(模块导入)

    什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的代码(.p ...

  10. IAR使用跳转功能时不正常的情况

    @2019-04-12 [小记] [使用环境]IAR-Arm8.30.1 [验证] 均为实测 1. 出现如下图这种情况应该是工程所在路径太深导致 2. 如果不弹出上图警告,但还是不跳转应该是工程编译信 ...