Servlet监听器详解


      Servlet API提供了基本的应用程序事件监听器接口。编程者可以通过实现这些Servlet2.4以后提供了对以下对象的事件监听:

  • ServletContext:可以使程序得知整个应用程序载入和卸载等运行情况;
  • HttpSession:可以Web程序了解应用程序会期间的状况并作出响应;
  • WebServletRequest可以使Web程序控制Web请求的生命周期。

      JavaServetAPI官方文档对各个事件监听器接口进行说明。

监听器接口描述

ServletContextListener

所在包: javax.servlet
接口声明: public interface ServletContextListener extends
java.util.EventListener
方法
1. void contextDestroyed(ServletContextEvent sce);当应用被卸载后触发执行该方法中的代码。
2. void contextInitialized(ServletContextEvent sce);当应用在初始化时触发执行该方法中的代码。

这里需要对 ServletContentEvent 说明一下, 它是一个ServletContext 对象的事件,其类的声明如下:

public class ServletContentEvent extends java.util.EventObject

包含方法:

ServletContext getServletContext(), 返回事件的Servlet 上文,即产生事件的当前应用程序。

ServletContextAttributeListener

所在包: javax.servlet
接口声明: public interface ServletContextAttributeListener
extends java.util.EventListener
方法
1. void attributeAdded(ServletContextAttributeEvent scab);当一个新的属性加入到Servlet 的上下文中后触发该方法中的代码。
2. void attributeRemoved(ServletContextAttributeEvent scab);当一个属性被从servlet 的上下文中移走后触发该方法中的代码。
3. void attributeReplaced(ServletContextAttributeEvent scab);当servlet 上下文中的一个属性的值被替换后触发该方法中的代码。

ServletContextAttributeEvent 是servlet 上下文里的属性的事件,其类声明如下:

public class ServletContextAttributeEvent
extends ServletContextEvent

包含方法:

  • String GetName();返回产生事件的属性名称;
  • Object GetValue();返回产生事件的属性的值。

HttpSessionListener

所在包: javax.servlet
接口声明: public interface HttpSessionListener
extends java.util.EventListener
方法
1. void sessionCreated(HttpSessionEvent se);当一个会话被创建后触发执行该方法中的代码。
2. void sessionDestroyed(HttpSessionEvent se);当一个会话被释放后触发执行该方法中的代码。

HttpSessionEvent 是会话事件类,其声明如下:

public class HttpSessionEvent
extends java.util.EventObject

包含方法: HttpSession getSession(), 返回产生事件的session 对象。

HttpSessionActivationListener

所在包: javax.servlet
接口声明: public interface HttpSessionActivationListener
extends java.util.EventListener
方法
1. void SessionDidActivate(HttpSessionEvent se)
2. void SessionWillPassivate(HttpSessionEvent se)

Activate 与Passivate 是用于置换对象的动作,当session 对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透过对象序列化),所作的动作称之为Passivate ,而硬盘或储存器上的session 对象重新加载JVM时所采的动作称之为Activate 。

HttpSessionAttributeListener

所在包 : javax.servlet
接口声明: public interface HttpSessionAttributeListener
extends java.util.EventListener
方法
1. void attributeAdded(HttpSessionBindingEvent se)
2. void attributeReplaced(HttpSessionBindingEvent se)
3. void attributeRemoved(HttpSessionBindingEvent se)

以上三个方法分别在会话属性被加入、会话属性值被修改和会话属性被移除时触发执行。

HttpSessionBindingEvent 是一个会话事件对象类,其声明如下:

public interface HttpSessionBindingListener
extends java.util.EventListener

包含方法:

  • String getName(), 返回产生当前事件的会话的属性名。
  • Object getValue(), 返回产生当前事件的会话的属性值。
  • HttpSession getSession(),返回产生当前事件的会话对象。

HttpSessionBindingListener

所在包: javax.servlet
接口声明: public interface HttpSessionBindingListener
extends java.util.EventListener
方法

  1. void valueBound(HttpSessionBindingEvent event);当实现 HttpSessionBindingListener 接口的对象被绑定到Session Attribute
    中,该对象的此方法被执行;

  2. void valueUnbound(HttpSessionBindingEvent event);当实现HttpSessionBindingListener 接口的对象被从Session Attribute 解除绑定,该对象的此方法被执行。

请注意 HttpSessionAttributeListener 与HttpSessionBindingListener 的区别:

  1. 前者是需要在web.xml 中进行描述的,后者不需要。
  2. 前者是在任何session 的属生变化时都会触发执行其方法中的代码, 而后者只是在实现它的对象被绑定到会话属性或被从会话属生中解除绑定时, 才会触发执行那个对象的valueBound 和valueUnboundy 这两个方法的代码。比如说有两个对象A和B都实现了HttpSessionBindingListener 接口, 当A被绑定到会话属性中时,只是A的valueBound() 方法被触发执行。

ServletRequestListener

所在包: javax.servlet
接口声明: public interface ServletRequestListener
extends java.util.EventListener
方法

  1. void RequestDestroyed(ServletRequestEvent evt)
  2. void RequestInitialized(ServletRequestEvent evt)

以上两个方法分别在ServetRequest 对象初始化和清除时触发执行。ServletRequestEvent 表示ServletReuest 事件类,其声明如下:

public class ServletRequestEvent
extends java.util.EventObject

包含方法:

  • ServletContext getServletContext(), 获得当前Web应用程序的上下文对象。
  • ServletRequest getServletRequest() ,获得当前事件的主体ServletRequest 对象。

ServletRequestAttributeListener

所在包: javax.servlet
接口声明: public interface ServletRequestAttributeListener
extends java.util.EventListener
方法

  1. void attributeAdded(ServletRequestAttributeEvent e);当向ServlvetRequest 对象属性中添加属性后触发执行该方法。

  2. void attributeRemoved(ServletRequestAttributeEvent e);当向ServlvetRequest 对象属性中移除属性后触发执行该方法。

  3. void attributeReplaced(ServletRequestAttributeEvent e);当修改ServlvetRequest 对象属性的属生值后触发执行该方法。

ServletRequestAttributeEvent 是ServletRequest 属性事件类,其声明如下:

public class ServletRequestAttributeEvent
extends ServletRequestEvent

包含方法:

  • String getName(), 获得触发事件的属性的名称。
  • Object getValue(),获得触发事件的属生的值。

监听器注册

      下面说明如何在web.xml 中布署事件监听器以实现对事件的处理,格式如下:

<listener>
    <listener-class>
        fey.servlet.listener.CustomServletContextListener
    </listener-class >
</listener>

      其中fey.servlet.listener.CustomServletContextListener 是实现上述各事件监听器接口的类名。当然,你需要将这些类放入Web容器的Web应用classes 或lib 目录下以让Web容器可以找到。

      另外说明一点,一个类可以一个或多个监听器接口。

监听器案例

统计并显示在线用户

      简例一:监听用户上线与退出,显示在线用户

      1、登陆页面 Login.jsp

<%@page pageEncoding="gb2312" contentType="text/html;charset=gb2312" %>
<%
    session=request.getSession(false);
    if(session!=null)session.invalidate();
%>
<html>
    <head><title></title></head>
    <body>
        <form action="isOnline.jsp" method="post">
            用户名: <input type="text" name="uName"/>
            <input type="submit" value=" 上线">
        </form>
    </body>
</html>

      2、控制页面(只是为了说明监听器问题,所以简单了点… ) isOnline.jsp

<%@page pageEncoding="gb2312" contentType="text/html;
charset=gb2312" %>
<html>
    <head><title></title></head>
    <body>
        <%
        session=request.getSession();
        session.setAttribute("userName",
                request.getParameter("uName"));
        response.sendRedirect("showOnline.jsp");
        %>
    </body>
</html>

      3、显示页面 showOnline.jsp

<%@page pageEncoding="gb2312" contentType="text/html; charset=gb2312"
import="java.util.ArrayList" %>
<html>
<head><title></title></head>
    <body>
        <%
            ArrayList
            showList=
                (ArrayList(getServletContext().
                    getAttribute("list"));
            out.print(" 在线人数 "+showList.size()+"<br>");
            for(int i=0;i<showList.size();i++){
                out.print(showList.get(i)+" 在线"+"<br>");
            }
        %>
        <br>
        <a href="Login.jsp"> 退出</a>
    </body>
</html>

      4、配置页面 web.xml

<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <listener>
        <listener-class>
            org.xiosu.listener.onlineListener
        </listener-class>
    </listener>
</web-app>

      5、监听器 onlineListener.java

package org.xiosu.listener;
import java.util.ArrayList;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class onlineListener implements HttpSessionListener,
HttpSessionAttributeListener {
    // 参数
    ServletContext sc;
    ArrayList list = new ArrayList();

    // 新建一个session 时触发此操作
    public void sessionCreated(HttpSessionEvent se) {
        sc=se.getSession().getServletContext();
        System.out.println(" 新建一个session");
    }

    // 销毁一个session 时触发此操作
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println(" 销毁一个 session");
        if (!list.isEmpty()) {
            list.remove((String) se.getSession()
                .getAttribute("userName"));
            sc.setAttribute("list", list);
        }
    }

    // 在session 中添加对象时触发此操作,在list 中添加一个对象
    public void attributeAdded(HttpSessionBindingEvent sbe) {
        list.add((String) sbe.getValue());
        sc.setAttribute("list", list);
    }

    // 修改、删除session 中添加对象时触发此操作
    public void attributeRemoved(HttpSessionBindingEvent arg0) {
    }

    public void attributeReplaced(HttpSessionBindingEvent arg0) {
    }
}

      在Web开发中关于监听器的应用,首先,也要在web.xml 配置文件中进行声明:在web.xml 文件中的声明如下: ( 声明片断) 要放在filter 过滤器声明和filter-mapping 声明后面。

<listener>
    <listener-class>
        markchen.web.listener.MySessionListener
    </listener-class>
</listener>
<listener>
    <listener-class>
        markchen.web.listener.MyServletContextListener
    </listener-class>
</listener>
// 这两个java 类的内容都和简单,仅仅是为了演示说明而已
//MySessionListener.java 文件的内容如下
//Web 应用程序中会话的生命周期监听器实现
package markchen.web.listener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MySessionListener implements HttpSessionListener {
// 在会话一创建时该方法被调用, 可以在此处编写自己需要做特殊处理的程序代码
    public void sessionCreated(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        String sessionId=session.getId();
        System.out.println("Session::::::"+
            sessionId+"******Created******");
    }
    // 在会话即将销毁时该方法被调用, 可以在此处编写自己需要做特殊处理的程序代码
    public void sessionDestroyed(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        String sessionId=session.getId();
        System.out.println("Session::::::"+
            sessionId+"******Destroyed******");
    }
}

      注意:在sessionDestroyed() 方法中一定不要再调用session.invalidate() 方法了,因为每调用一次session.invalidate() 方法都会触发sessionDestroyed() 方法的调用,进而形成死循环,最终使Web应用程序意外终止。

//MyServletContextListener.java
//Web 应用程序的生命周期监听器实现
package markchen.web.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener
{
    // 在Web应用程序初始化后该方法被调用
    public void contextInitialized(ServletContextEvent event) {
        System.out.println("******Application
        started******");
    }
    // 在Web应用程序销毁时该方法被调用
    public void contextDestroyed(ServletContextEvent event) {
        System.out.println("******Application
        ended******");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值