這個J2EE小提示闡述了ServletContextListener的用法。這個事件類作為Web應(yīng)用服務(wù)的一部分,處理Web應(yīng)用的 servlet上下文
(context)的變化的通知。這可以解釋為,好像有個人在服務(wù)器旁不斷地通知我們服務(wù)器在發(fā)生什么事件。那當(dāng)然需要監(jiān)聽者了。
因 此,在通知上下文(context)初始化和銷毀的時候,ServletContextListner非常有用。


import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.*;
 
public    class MyListener implements ServletContextListener {   
     
private ServletContext context = null

         
/** 這個方法在Web應(yīng)用服務(wù)被移除,沒有能力再接受請求的時候被調(diào)用。     */   
     
public void contextDestroyed(ServletContextEvent event){       
         
//Output a simple message to the server's console       
     System.out.println("The Simple Web App. Has Been Removed");     
     
this.context = null;    }
   
     
     
     
// 這個方法在Web應(yīng)用服務(wù)做好接受請求的時候被調(diào)用。   
    public void contextInitialized(ServletContextEvent event){     
       
this.context = event.getServletContext();     
       
//Output a simple message to the server's console      
       System.out.println("The Simple Web App. Is Ready");  
       }

}


<web-app>
<listener>
<listener-class>
com.listeners.MyContextListener
</listener-class>
</listener>
<servlet/>
<servlet-mapping/>
</web-app> 
 
下面是spring中的ContextLoaderListener,我們可以看看里面的代碼
public class ContextLoaderListener implements ServletContextListener {

    
private ContextLoader contextLoader;


    
/**
     * Initialize the root web application context.
     
*/

    
public void contextInitialized(ServletContextEvent event) {
        
this.contextLoader = createContextLoader();
        
this.contextLoader.initWebApplicationContext(event.getServletContext());
    }


    
/**
     * Create the ContextLoader to use. Can be overridden in subclasses.
     * 
@return the new ContextLoader
     
*/

    
protected ContextLoader createContextLoader() {
        
return new ContextLoader();
    }


    
/**
     * Return the ContextLoader used by this listener.
     
*/

    
public ContextLoader getContextLoader() {
        
return contextLoader;
    }



    
/**
     * Close the root web application context.
     
*/

    
public void contextDestroyed(ServletContextEvent event) {
        
if (this.contextLoader != null{
            
this.contextLoader.closeWebApplicationContext(event.getServletContext());
        }

    }


}

  <listener>       
          
<listener-class> org.springframework.web.context.ContextLoaderListener </listener-class>       
   
</listener> 
ServletContextListener接口有兩方需要實(shí)現(xiàn)的方法:contextInitialized()和contextDestroyed();
Listener,譯為監(jiān)聽者.顧名思義,它會監(jiān)聽Servlet容器,當(dāng)應(yīng)用開始的時候它會調(diào)用contextInitialized()方法;
當(dāng)應(yīng)用關(guān)閉的時候,它同樣會調(diào)用contextDestroyed()方法.我們可以利用這個特性初始化一些信息,當(dāng)然我們
也可以利用Servlet類init()方法,并在配置文件中讓它啟動應(yīng)用的時候就執(zhí)行,并且在關(guān)閉的時候執(zhí)行destroy()方
法.但是繼承此接口應(yīng)該更符合容器的應(yīng)用.
 

舉個簡單的例子:在一些論壇,社區(qū)及聊天室當(dāng)中,刪除在線的超時用戶就可以利用這個接口來實(shí)現(xiàn).

可以利用JAVA的TimerTask及Timer類來實(shí)現(xiàn)每隔一定的時間進(jìn)行自動檢測.
實(shí)例代碼如下:

UserOnlineTimerTask.java
-----------------
package com.bcxy.servlet;
import java.util.TimerTask;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class UserOnlineTimerTask extends TimerTask {
Log log 
= LogFactory.getLog(UserOnlineTimerTask.class);

public void run() {
// 刪除超時在線用戶
log.info("刪除在線的超時用戶.");
}

}
SysListener.java
-----------------------------------
 
package com.bcxy.servlet;
import java.io.IOException;
import java.util.Timer;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SysListener
extends HttpServlet
implements ServletContextListener {

Log log 
= LogFactory.getLog(SysListener.class);
Timer timer 
= new Timer();
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
//
}


public void contextInitialized(ServletContextEvent sce) {

log.info(
"initial context.");

timer.schedule(
new UserOnlineTimerTask(), 010000);
}


public void contextDestroyed(ServletContextEvent sce) {

log.info(
"destory context.");
timer.cancel();
}

}
 
 
HttpSessionListener
繼承HttpSessionListener接口的類,來監(jiān)聽Session創(chuàng)建和銷毀的事件

import javax.servlet.*;
import javax.servlet.http.*;
import jp.co.sysmex.sps.app.web.WebAccountBean;

//①HttpSessionListener 接口的實(shí)現(xiàn)。
public class CheckSessionServlet implements HttpSessionListener {
    
private static int sesCount = 0;

    
//②session生成時觸發(fā)sessionCreated方法
    public void sessionCreated(HttpSessionEvent hse) {
        sesCount
++;
        
//ServletContext sc = hse.getSession().getServletContext();
        String sessid = hse.getSession().getId();
        
        System.out.println(
" session Created " + sesCount);
        System.out.println(
" session ++ " + sessid);
    }


    
//③session無效時觸發(fā)sessionDestroyed方法
    
//此時session中的內(nèi)容還可以正常取道
    public void sessionDestroyed(HttpSessionEvent hse) {
        String sessid 
= hse.getSession().getId();
        
        System.out.println(
" session Destroyed " + sesCount);
        System.out.println(
" session -- " + sessid);
        
        WebAccountBean account 
=  (WebAccountBean)(hse.getSession().getAttribute("ACCOUNT_KEY"));
        System.out.println(account.getEnterpriseCode());
        System.out.println(account.getEnterpriseFullKanjiName());
        
        sesCount
--;
    }

}


web.xml文件中增加配置信息.
<listener> 
   
<listener-class>jp.co.sysmex.sps.util.CheckSessionServlet</listener-class>
 
</listener>