Listener是Servlet的監聽器,它可以監聽用戶端的請求、服務端的操作等。通過監聽器,可以自動激發一些操作,比如監聽線上的使用者的數量。當增加一個HttpSession時,就激發sessionCreated(HttpSessionEvent se)方法,這樣就可以給線上人數加1。常用的監聽介面有以下幾個:
ServletContextAttributeListener監聽對ServletContext屬性的操作,比如增加、刪除、修改屬性。
ServletContextListener監聽ServletContext。當建立ServletContext時,激發contextInitialized(ServletContextEvent sce)方法;當銷毀ServletContext時,激發contextDestroyed(ServletContextEvent sce)方法。
HttpSessionListener監聽HttpSession的操作。當建立一個Session時,激發session Created(HttpSessionEvent se)方法;當銷毀一個Session時,激發sessionDestroyed (HttpSessionEvent se)方法。
HttpSessionAttributeListener監聽HttpSession中的屬性的操作。當在Session增加一個屬性時,激發attributeAdded(HttpSessionBindingEvent se) 方法;當在Session刪除一個屬性時,激發attributeRemoved(HttpSessionBindingEvent se)方法;當在Session屬性被重新設定時,激發attributeReplaced(HttpSessionBindingEvent se) 方法。 下面我們開發一個具體的例子,這個監聽器能夠統計線上的人數。在ServletContext初始化和銷毀時,在伺服器控制台列印對應的資訊。當ServletContext裡的屬性增加、改變、刪除時,在伺服器控制台列印對應的資訊。
要獲得以上的功能,監聽器必須實現以下3個介面:
HttpSessionListener
ServletContextListener
ServletContextAttributeListener 我們看具體的代碼,見樣本14-9。
【程式原始碼】
1// ==================== Program Discription =====================2// 程式名稱:樣本14-9 : EncodingFilter .java3// 程式目的:學習使用監聽器4// ==============================================================5import javax.servlet.http.*;6import javax.servlet.*;78public class OnLineCountListener implements HttpSessionListener,ServletContextListener,ServletContextAttributeListener9{10private int count;11private ServletContext context = null;1213public OnLineCountListener()14{15count=0;16//setContext();17}18//建立一個session時激發19public void sessionCreated(HttpSessionEvent se) 20{21count++;22setContext(se);2324}25//當一個session失效時激發26public void sessionDestroyed(HttpSessionEvent se) 27{28count--;29setContext(se);30}31//設定context的屬性,它將激發attributeReplaced或attributeAdded方法32public void setContext(HttpSessionEvent se)33{34se.getSession().getServletContext().setAttribute("onLine",new Integer(count));35}36 //增加一個新的屬性時激發37public void attributeAdded(ServletContextAttributeEvent event) {3839log("attributeAdded('" + event.getName() + "', '" +40 event.getValue() + "')");4142 }43 44 //刪除一個新的屬性時激發45 public void attributeRemoved(ServletContextAttributeEvent event) {4647log("attributeRemoved('" + event.getName() + "', '" +48 event.getValue() + "')");4950 }5152//屬性被替代時激發53 public void attributeReplaced(ServletContextAttributeEvent event) {5455log("attributeReplaced('" + event.getName() + "', '" +56 event.getValue() + "')");57 }58 //context刪除時激發59 public void contextDestroyed(ServletContextEvent event) {6061log("contextDestroyed()");62this.context = null;6364 }6566 //context初始化時激發67 public void contextInitialized(ServletContextEvent event) {6869this.context = event.getServletContext();70log("contextInitialized()");7172 }73 private void log(String message) {7475 System.out.println("ContextListener: " + message);76 } 77} |
【程式註解】
在OnLineCountListener裡,用count代表當前線上的人數,OnLineCountListener將在Web伺服器啟動時自動執行。當OnLineCountListener構造好後,把count設定為0。每增加一個Session,OnLineCountListener會自動調用sessionCreated(HttpSessionEvent se)方法;每銷毀一個Session,OnLineCountListener會自動調用sessionDestroyed(HttpSessionEvent se)方法。當調用sessionCreated(HttpSessionEvent se)方法時,說明又有一個客戶在請求,此時使線上的人數(count)加1,並且把count寫到ServletContext中。ServletContext的資訊是所有用戶端共用的,這樣,每個用戶端都可以讀取到當前線上的人數。
為了使監聽器生效,需要在web.xml裡進行配置,如下所示:
<listener> <listener-class>OnLineCountListener</listener-class> </listener> |
測試程式:
<%@ page contentType="text/html;charset=gb2312" %> |
目前線上人數:
<font color=red><%=getServletContext().getAttribute("onLine")%></font><br> |
退出會話:
<form action="exit.jsp" method=post><input type=submit value="exit"></form> |
getServletContext().getAttribute("onLine")獲得了count的具體值。用戶端調用
<%session.invalidate() ;%> |
使Session失效,這樣監聽器就會使count減1。
【運行程式】
web.xml做好以上的配置,把OnLineCountListener放在WEB-INF/class目錄下,啟動Web伺服器,在瀏覽器裡輸入以下URL(根據具體情況不同):http://127.0.0.1:8080/ch14/listener.jsp
瀏覽器將會列印目前線上人數。在伺服器端有以下輸出:
…ContextListener: contextInitialized()ContextListener: attributeReplaced('org.apache.catalina.WELCOME_FILES', '[Ljava.lang.String;@1d98a')…ContextListener: attributeAdded('onLine', '1')ContextListener: attributeReplaced('onLine', '1')ContextListener: attributeReplaced('onLine', '0')ContextListener: attributeReplaced('onLine', '1')ContextListener: attributeReplaced('onLine', '2') |
(T111)
本文選自飛思圖書《精通Java核心技術》