Listener详解

一.基础知识

JSP/Servlet中的事件处理写过AWT或Swing程序的人一定对桌面程序的事件处理机制印象深刻:通过实现Listener接口的类可以在特定事件(Event)发生时,呼叫特定的方法来对事件进行响应。

其实我们在编写JSP/Servle程序时,也有类似的事件处理机制,所不同的是在JSP/Servlet中是在web.xml中注册Listener,由Container在特定事件发生时呼叫特定的实现Listener的类。

1. Servlet中的Listener和Event:

在JSP 2.0/Servlet 2.4中,共有八个Listener接口,六个Event类别。
ServletContextListener接口
[接口方法] contextInitialized()与contextDestroyed()
[接收事件] ServletContextEvent
[触发场景] 在Container加载Web应用程序时(例如启动 Container之后),会呼叫contextInitialized(),而当容器移除Web应用程序时,会呼叫contextDestroyed ()方法。


ServletContextAttributeListener
[
接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] ServletContextAttributeEvent
[触发场景] 若有对象加入为application(ServletContext)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、attributeRemoved()。


HttpSessionListener
[
接口方法] sessionCreated()与sessionDestroyed ()
[接收事件] HttpSessionEvent
[触发场景] 在session (HttpSession)对象建立或被消灭时,会分别呼叫这两个方法。


HttpSessionAttributeListener
[
接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为session(HttpSession)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。


HttpSessionActivationListener
[
接口方法] sessionDidActivate()与sessionWillPassivate()
[接收事件] HttpSessionEvent
[触发场景] Activate与Passivate是用于置换对象的动作,当session对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透 过对象序列化),所作的动作称之为Passivate,而硬盘或储存器上的session对象重新加载JVM时所采的动作称之为Activate,所以容 易理解的,sessionDidActivate()与 sessionWillPassivate()分别于Activeate后与将Passivate前呼叫。


ServletRequestListener
[
接口方法] requestInitialized()与 requestDestroyed()
[接收事件] RequestEvent
[触发场景] 在request(HttpServletRequest)对象建立或被消灭时,会分别呼叫这两个方法。


ServletRequestAttributeListener
[
接口方法] attributeAdded()、 attributeReplaced()、attributeRemoved()
[接收事件] HttpSessionBindingEvent
[触发场景] 若有对象加入为request(HttpServletRequest)对象的属性,则会呼叫attributeAdded(),同理在置换属性与移除属性时,会分别呼叫attributeReplaced()、 attributeRemoved()。


HttpSessionBindingListener
[
接口方法] valueBound()与valueUnbound()
[接收事件] HttpSessionBindingEvent
[触 发场景] 实现HttpSessionBindingListener接口的类别,其实例如果被加入至session(HttpSession)对象的属性中,则会 呼叫 valueBound(),如果被从session(HttpSession)对象的属性中移除,则会呼叫valueUnbound(),实现 HttpSessionBindingListener接口的类别不需在web.xml中设定。


2.如何注册Servlet中的事件
实现上面这几个接口的类别,除了HttpSessionBindingListener外,必须在web.xml中向容器注册,容器才会在对应的事件发生时呼叫对应的类别,如:
 < listener > 
 < listener-class >demo.servlet.listener.CustomServletContextListener </ listener-class> 
 </ listener >

 

3.Java类简单实例
==========
//
侦听启动和关闭
import javax.servlet.ServletContextListener;
import javax.servlet.*;

public class TigerListen implementsServletContextListener {
 public void contextInitialized(ServletContextEvent sce)
 {
  System.out.print("Init") ;
 }
 public void contextDestroyed(ServletContextEvent sce)
 {
  System.out.print("Destroved") ;
 }
}

 

对应的web.xml
============
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <listener>
  <listener-class>TigerListen</listener-class>
 </listener>
</web-app>

 

二.高级应用

Java Servlet Listener实现定时监听

分两步走:

(1)实现 javax.servlet.ServletContextListener 接口的两个方法:contextInitialized和contextDestroyed

contextInitialized:当Servlet容器启动时会执行

contextDestroyed:当Servlet容器停止时会执行

(2)在contextInitialized()中加入需要监听的程序,并由java.util.Timer 的 schedule() 方法来控制监听程序执行的频率

    DEMO(这是我的一个短信回复监听的程序原型,精简了一下)

    ReplyListener.java

package com. jackson.jcms;
  import javax.servlet.*;
      public class ReplyListener implements ServletContextListener {
  private ReplyTimer rt = null;
  public void contextInitialized(ServletContextEvent event) {
  String status = "[SYS] SMS reply listener start .";
  event.getServletContext().log(status);
  System.out.println(status);
  rt = new ReplyTimer(1);
  rt.start();
  }

 
  public void contextDestroyed(ServletContextEvent event) {
  String status = "[SYS] SMS reply listener stop .";
  event.getServletContext().log(status);
  System.out.println(status);
  if (rt != null) {
  rt.stop();
  }
  }
  }

-------------------------------------------------
  ReplyTimer.java

package com. jackson.jcms;
  import java.util.*;

public class ReplyTimer {
  private final Timer timer = new Timer();
  private final int min;
  
  public ReplyTimer(int minutes) {
  min = minutes;
  }
  
  public void start() {
  Date date = new Date();
  timer.schedule(new ReplyTask(), date, min * 60 * 1000);
  }
  
  public void stop() {
  timer.cancel();
  }
  }

-------------------------------------------------
  ReplyTask.java
  package com. jackson.jcms;
  import java.util.*;
  
  public class ReplyTask extends TimerTask {
  public void doSomething() {
  System.out.println("[SYS] SMS reply listener running ");
  } 
  public void run() {
  doSomething();
  }
  }

将编译好的class文件放入WEB-INF/classes中,最后别忘记在Servlet容器中当前WEB应用的web.xml中加入监听语句

<listener>
<listener-class>com.jackson.jcms.ReplyListener</listener-class>
</listener>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值