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 .java
3 // 程序目的:學習使用監聽器
4 // ==============================================================
5 import javax.servlet.http.*;
6 import javax.servlet.*;
7
8 public class OnLineCountListener implements HttpSessionListener,
ServletContextListener,ServletContextAttributeListener
9 {
10 private int count;
11 private ServletContext context = null;
12
13 public OnLineCountListener()
14 {
15 count=0;
16 //setContext();
17 }
18 //創建一個session時激發
19 public void sessionCreated(HttpSessionEvent se)
20 {
21 count++;
22 setContext(se);
23
24 }
25 //當一個session失效時激發
26 public void sessionDestroyed(HttpSessionEvent se)
27 {
28 count--;
29 setContext(se);
30 }
31 //設置context的屬性,它將激發attributeReplaced或attributeAdded方法
32 public void setContext(HttpSessionEvent se)
33 {
34 se.getSession().getServletContext().
setAttribute("onLine",new Integer(count));
35 }
36 //增加一個新的屬性時激發
37 public void attributeAdded(ServletContextAttributeEvent event) {
38
39 log("attributeAdded('" + event.getName() + "', '" +
40 event.getValue() + "')");
41
42 }
43
44 //刪除一個新的屬性時激發
45 public void attributeRemoved(ServletContextAttributeEvent event) {
46
47 log("attributeRemoved('" + event.getName() + "', '" +
48 event.getValue() + "')");
49
50 }
51
52 //屬性被替代時激發
53 public void attributeReplaced(ServletContextAttributeEvent event) {
54
55 log("attributeReplaced('" + event.getName() + "', '" +
56 event.getValue() + "')");
57 }
58 //context刪除時激發
59 public void contextDestroyed(ServletContextEvent event) {
60
61 log("contextDestroyed()");
62 this.context = null;
63
64 }
65
66 //context初始化時激發
67 public void contextInitialized(ServletContextEvent event) {
68
69 this.context = event.getServletContext();
70 log("contextInitialized()");
71
72 }
73 private void log(String message) {
74
75 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核心技術》 |