web上下文監聽器ServletContextListener 例子 .


這個J2EE小提示闡述了ServletContextListener的用法。這個事件類作為Web應用服務的一部分,處理Web應用的 servlet上下文(context)的變化的通知。這可以解釋為,好像有個人在服務器旁不斷地通知我們服務器在發生什么事件。那當然需要監聽者了。因此,在通知上下文(context)初始化和銷毀的時候,ServletContextListner非常有用。
Java代碼 復制代碼  收藏代碼
  1. package com.listeners;   
  2. import javax.servlet.ServletContextListener;   
  3.   
  4. import javax.servlet.ServletContextEvent;   
  5. import javax.servlet.*;   
  6. public class MyContextListener implements ServletContextListener {   
  7. private ServletContext context = null;   
  8.   
  9.  public void contextDestroyed(ServletContextEvent event){   
  10.   //Output a simple message to the server's console   
  11.   System.out.println("The Simple Web App. Has Been Removed");   
  12.   this.context = null;   
  13. }   
  14.  // 這個方法在Web應用服務做好接受請求的時候被調用。   
  15. public void contextInitialized(ServletContextEvent event){   
  16.   this.context = event.getServletContext();   
  17.   //Output a simple message to the server's console   
  18.   System.out.println("The Simple Web App. Is Ready");   
  19. }   
  20. }  
  1. package com.listeners;  
  2. import javax.servlet.ServletContextListener;  
  3.   
  4. import javax.servlet.ServletContextEvent;  
  5. import javax.servlet.*;  
  6. public class MyContextListener implements ServletContextListener {  
  7. private ServletContext context = null;  
  8.   
  9.  public void contextDestroyed(ServletContextEvent event){  
  10.   //Output a simple message to the server's console   
  11.   System.out.println("The Simple Web App. Has Been Removed");  
  12.   this.context = null;  
  13. }  
  14.  // 這個方法在Web應用服務做好接受請求的時候被調用。   
  15. public void contextInitialized(ServletContextEvent event){  
  16.   this.context = event.getServletContext();  
  17.   //Output a simple message to the server's console   
  18.   System.out.println("The Simple Web App. Is Ready");  
  19. }  
  20. }  
package com.listeners;
import javax.servlet.ServletContextListener;

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

 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應用服務做好接受請求的時候被調用。
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.XML中
Xml代碼 復制代碼  收藏代碼
  1. <web-app>  
  2. <listener>  
  3.   <listener-class>  
  4.    com.listeners.MyContextListener   
  5.   </listener-class>  
  6. </listener>  
  7. <servlet/>  
  8. <servlet-mapping/>  
  9. </web-app>  
  1. <web-app>  
  2. <listener>  
  3.   <listener-class>  
  4.    com.listeners.MyContextListener  
  5.   </listener-class>  
  6. </listener>  
  7. <servlet/>  
  8. <servlet-mapping/>  
  9. </web-app>  
<web-app>
<listener>
  <listener-class>
   com.listeners.MyContextListener
  </listener-class>
</listener>
<servlet/>
<servlet-mapping/>
</web-app>


ServletContextListener接口有兩方需要實現的方法:
contextInitialized()和contextDestroyed();
Listener,譯為監聽者.顧名思義,它會監聽Servlet容器,當應用開始的時候它會調用contextInitialized()方法;
當應用關閉的時候,它同樣會調用contextDestroyed()方法.
我們可以利用這個特性初始化一些信息,當然我們也可以利用Servlet類init()方法,並在配置文件中讓它啟動應用的時候
就執行,並且在關閉的時候執行destroy()方法.但是繼承此接口應該更符合容器的應用.
舉個簡單的例子:在一些論壇,社區及聊天室當中,刪除在線的超時用戶就可以利用這個接口來實現.
可以利用JAVA的TimerTask及Timer類來實現每隔一定的時間進行自動檢測.
實例代碼如下:

UserOnlineTimerTask.java
Java代碼 復制代碼  收藏代碼
  1. package com.bcxy.servlet;   
  2. import java.util.TimerTask;   
  3. import org.apache.commons.logging.Log;   
  4. import org.apache.commons.logging.LogFactory;   
  5. public class UserOnlineTimerTask extends TimerTask {   
  6. Log log = LogFactory.getLog(UserOnlineTimerTask.class);   
  7. public void run() {   
  8. // 刪除超時在線用戶   
  9. log.info("刪除在線的超時用戶....");   
  10. }   
  11. }  
  1. package com.bcxy.servlet;  
  2. import java.util.TimerTask;  
  3. import org.apache.commons.logging.Log;  
  4. import org.apache.commons.logging.LogFactory;  
  5. public class UserOnlineTimerTask extends TimerTask {  
  6. Log log = LogFactory.getLog(UserOnlineTimerTask.class);  
  7. public void run() {  
  8. // 刪除超時在線用戶   
  9. log.info("刪除在線的超時用戶....");  
  10. }  
  11. }  
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
Java代碼 復制代碼  收藏代碼
  1. package com.bcxy.servlet;   
  2. import java.io.IOException;   
  3. import java.util.Timer;   
  4. import javax.servlet.ServletContextEvent;   
  5. import javax.servlet.ServletContextListener;   
  6. import javax.servlet.ServletException;   
  7. import javax.servlet.ServletRequest;   
  8. import javax.servlet.ServletResponse;   
  9. import javax.servlet.http.HttpServlet;   
  10. import org.apache.commons.logging.Log;   
  11. import org.apache.commons.logging.LogFactory;   
  12. public class SysListener   
  13. extends HttpServlet   
  14. implements ServletContextListener {   
  15. Log log = LogFactory.getLog(SysListener.class);   
  16. Timer timer = new Timer();   
  17. public void service(ServletRequest request, ServletResponse response)   
  18. throws ServletException, IOException {   
  19. //   
  20.   
  21. }   
  22. public void contextInitialized(ServletContextEvent sce) {   
  23. log.info("initial context....");   
  24. timer.schedule(new UserOnlineTimerTask(), 010000);   
  25.   
  26. }   
  27. public void contextDestroyed(ServletContextEvent sce) {   
  28. log.info("destory context....");   
  29. timer.cancel();   
  30. }   
  31.   
  32. }  
  1. package com.bcxy.servlet;  
  2. import java.io.IOException;  
  3. import java.util.Timer;  
  4. import javax.servlet.ServletContextEvent;  
  5. import javax.servlet.ServletContextListener;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.ServletRequest;  
  8. import javax.servlet.ServletResponse;  
  9. import javax.servlet.http.HttpServlet;  
  10. import org.apache.commons.logging.Log;  
  11. import org.apache.commons.logging.LogFactory;  
  12. public class SysListener  
  13. extends HttpServlet  
  14. implements ServletContextListener {  
  15. Log log = LogFactory.getLog(SysListener.class);  
  16. Timer timer = new Timer();  
  17. public void service(ServletRequest request, ServletResponse response)  
  18. throws ServletException, IOException {  
  19. //   
  20.   
  21. }  
  22. public void contextInitialized(ServletContextEvent sce) {  
  23. log.info("initial context....");  
  24. timer.schedule(new UserOnlineTimerTask(), 010000);  
  25.   
  26. }  
  27. public void contextDestroyed(ServletContextEvent sce) {  
  28. log.info("destory context....");  
  29. timer.cancel();  
  30. }  
  31.   
  32. }  
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(), 0, 10000);

}
public void contextDestroyed(ServletContextEvent sce) {
log.info("destory context....");
timer.cancel();
}

}

如果你沒有使用log4j的話,你可以把log.info()改為System.out.println()會得到同樣的結果.

 

在Servlet API中有一個ServletContextListener接口,它能夠監聽ServletContext對象的生命周期,實際上就是監聽Web應用的生命周期。

當Servlet容器啟動或終止Web應用時,會觸發ServletContextEvent事件,該事件由 ServletContextListener 來處理。在 ServletContextListener 接口中定義了處理ServletContextEvent事件的兩個方法。

contextInitialized(ServletContextEvent sce):當Servlet容器啟動Web應用時調用該方法。在調用完該方法之后,容器再對Filter初始化,並且對那些在Web應用啟動時就需要被初始化的Servlet進諧跏薊?/P>

contextDestroyed(ServletContextEvent sce):當Servlet容器終止Web應用時調用該方法。在調用該方法之前,容器會先銷毀所有的Servlet和Filter過濾器。

下面通過一個例子來介紹ServletContextListener的用法。本章4.4.1節的例程4-9的CounterServlet類只能統計當Web應用啟動后,網頁被客戶端訪問的次數。如果重新啟動Web應用,計數器又會重新從1開始統計訪問次數。在實際應用中,往往需要統計自Web應用被發布后網頁被客戶端訪問的次數,這就要求當Web應用被終止時,計數器的數值被永久存儲在一個文件中或者數據庫中,等到Web應用重新啟動時,先從文件或數據庫中讀取計數器的初始值,然后在此基礎上繼續計數。

向文件中寫入或讀取計數器的數值的功能可以由自定義的 MyServletContextListener類(參見例程4-11)來完成,它具有以下功能:

在 Web 應用啟動時從文件中讀取計數器的數值,並把表示計數器的 Counter對象存放到 Web 應用范圍內。存放計數器的文件的路徑為helloapp/count/count.txt。

在Web應用終止時把Web應用范圍內的計數器的數值保存到count.txt文件中。

例程4-11 MyServletContextListener.java

 

public class MyServletContextListener implements ServletContextListener{

public void contextInitialized(ServletContextEvent sce){

System.out.println("helloapp application is Initialized.");

    //獲取ServletContext對象

ServletContext context=sce.getServletContext();

    try{

//從文件中讀取計數器的數值

BufferedReader reader=new BufferedReader(

new InputStreamReader(context.

getResourceAsStream("/count/count.txt")));

int count=Integer.parseInt(reader.readLine());

reader.close();

      //創建計數器對象

Counter counter=new Counter(count);

//把計數器對象保存到Web應用范圍

context.setAttribute("counter",counter);

}catch(IOException e){e.printStackTrace();}

}

public void contextDestroyed(ServletContextEvent sce){

System.out.println("helloapp application is Destroyed.");

    //獲取ServletContext對象

ServletContext context=sce.getServletContext();

    //從Web應用范圍獲得計數器對象

Counter counter=(Counter)context.getAttribute("counter");

    if(counter!=null){

try{

//把計數器的數值寫到count.txt文件中

String filepath=context.getRealPath("/count");

filepath=filepath+"/count.txt";

PrintWriter pw=new PrintWriter(filepath);

pw.println(counter.getCount());

pw.close();

}catch(IOException e){e.printStackTrace();}

}

}

}

用戶自定義的MyServletContextListener監聽器只有先向Servlet容器注冊,Servlet容器在啟動或終止Web應用時,才會調用該監聽器的相關方法。在web.xml文件中,<listener>元素用於向容器注冊監聽器:

 

 

 

Tips

<listener>

<listener-class>mypack.MyServletContextListener<listener-class />

</listener>

 

下面按如下步驟演示MyServletContextListener監聽器的作用。

(1)在helloapp/count目錄下創建count.txt文件,在該文件中存放了一個數字“5”。

(2)啟動 Tomcat。在瀏覽器中通過 http://localhost:8080/helloapp/counter 訪問CounterServlet,在第一次訪問該Servlet時,瀏覽器端顯示計數器的值為5。

(3)刷新上述訪問 CounterServlet 的頁面,會看到每刷新一次,計數器的值增加1,假定最后一次刷新后的計數器的值為10。

(4)手工終止helloapp應用。查看helloapp/count/count.txt文件,會發現在該文件中存放的數字變為10。

(5)手工重新啟動 helloapp 應用。在瀏覽器中再次訪問 CounterServlet,當第一次訪問該Servlet時,瀏覽器端顯示計數器的值為10。

從上述實驗中可以看出,MyServletContextListener 監聽器與 CounterServlet 共享Web應用范圍內的代表計數器的Counter對象。監聽器在Web應用啟動或終止時會操縱Counter對象,而Servlet在每次響應客戶請求時會操縱Counter對象。

觀察MyServletContextListener及本章4.3.4節的名為lifeInit的 LifeServlet在 Tomcat 控制台的打印結果的先后順序,會發現當 Web 應用啟動時,Servlet容器先調用MyServletContextListener的contextInitialized()方法,再調用lifeInit的init()方法;當Web應用終止時,Servlet容器先調用lifeInit的destroy()方法,再調用MyServletContextListener的contextDestroyed()方法。由此可見,在Web應用的生命周期中,ServletContext對象最早被創建,最晚被銷毀

ServletContextListener接口有兩方需要實現的方法:contextInitialized()和contextDestroyed();

Listener,譯為監聽者.顧名思義,它會監聽Servlet容器,當應用開始的時候它會調用contextInitialized()方法;

當應用關閉的時候,它同樣會調用contextDestroyed()方法.我們可以利用這個特性初始化一些信息,當然我們

也可以利用Servlet類init()方法,並在配置文件中讓它啟動應用的時候就執行,並且在關閉的時候執行destroy()方

法.但是繼承此接口應該更符合容器的應用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM