Servlet中的監聽器及監聽在線人數實例

Servlet API提供了基本的應用程序事件監聽器接口。編程者可以通過實現這些接口來使用管理事件的功能。Servlet2.4以後提供了對以下對象的事件監聽:ServletContext,HttpSession,ServletRequest。監聽ServletContext可以使Web程序得知整個應用程序載入和卸載等運行情況。監聽HttpSession可以Web程序瞭解應用程序會期間的狀況並作出響應。監聽ServletRequest可以使 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容器可以找到。外說明一點,一個類可以一個或多個監聽器接口。


九、實例:session的2個監聽器接口監聽當前在線人數列表
1、javax.servlet.http.HttpSessionBindingListener;
實現這個接口的類,每當被存放到session或從session中移除都會出發接口中相應的方法,從而實現監聽的效果。
2、javax.servlet.http.HttpSessionListener;
實現這個接口的類,本身就是1個監聽器,每當有session生成或消亡時,都觸發接口中相應的方法,從而實現監聽器的效果;
HttpSessionListener的實現類本身就是一個監聽器,要使用它需要在web.xml中啓動這個監聽器,例如
<listener>  
 <listener-class>packname.classname</listener-class>  
</listener> 
3、這2個監聽器是有區別的
前者的觸發取決於session中加入的屬性。
後者的觸發取決於session本身的產生和消亡。
4、與和上述之類似的還有對ServletContext的監聽和對Request監聽。
 
在線人數列表是對所有人起作用,數據應放到application中即ServletContext對象。
OnLineDemo.java  
import java.util.ArrayList;   
import java.util.List;   
import javax.servlet.ServletContext;   
import javax.servlet.ServletContextEvent;   
import javax.servlet.ServletContextListener;   
import javax.servlet.http.HttpSessionAttributeListener;   
import javax.servlet.http.HttpSessionBindingEvent;   
import javax.servlet.http.HttpSessionEvent;   
import javax.servlet.http.HttpSessionListener;   

public class OnlineDemo implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {  
   
    // 聲明一個ServletContext對象   
    private ServletContext application = null;   
  
    public void contextInitialized(ServletContextEvent sce) {   
        // 容器初始化時,向application中存放一個空的容器   
        this.application = sce.getServletContext();   
        this.application.setAttribute("alluser", new ArrayList());   
    }   
  
    public void contextDestroyed(ServletContextEvent sce) {   
    }   
  
    public void sessionCreated(HttpSessionEvent se) {   
    }   
  
    public void sessionDestroyed(HttpSessionEvent se) {   
        // 將用戶名稱從列表中刪除   
        List l = (List) this.application.getAttribute("alluser");   
        String value = (String) se.getSession().getAttribute("uname");   
        l.remove(value);   
        this.application.setAttribute("alluser", l);   
    }   
  
    public void attributeAdded(HttpSessionBindingEvent se) {   
        // 如果登陸成功,則將用戶名保存在列表之中   
        List l = (List) this.application.getAttribute("alluser");   
        l.add(se.getValue());   
        this.application.setAttribute("alluser", l);   
    }   
  
    public void attributeRemoved(HttpSessionBindingEvent se) {   
    }   
  
    public void attributeReplaced(HttpSessionBindingEvent se) {   
    }   

online.jsp
<%@ page contentType="text/html;charset=gb2312"%> 
<%@ page import="java.util.*"%> 
<form action="online.jsp" method="post">     
 <input type="text" name="name">  
 <input type="submit" value="登陸">  
 <a href="logout.jsp">註銷</a>  
</form>  
 
<%   
    if(request.getParameter("name")!=null)   
        session.setAttribute("uname",request.getParameter("name")) ;   
%>  
<h2>在線人員</h2>  
<hr>  
<%   
    List l = (List)application.getAttribute("allUser");   
    for(Object o : l)   
        out.println(o);   
%>
logout.jsp
<%   
    session.invalidate() ;   
%>
原帖地址:http://blog.sina.com.cn/s/blog_705c12080100nayb.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章