關于 Servlet 中的事件監聽
在 Servlet2.3 規范中添加了一些監聽 web 應用中重要事件的能力。這項功能可以讓我們根據事件的狀態更有效的對資源進行管理和自動化進行。這部分描述了 servlet 的事件監聽,包含以下部分:
1. ? 事件的分類和 Listener 接口
2. ? 典型的事件監聽過程
3. ? 事件監聽的聲明和調用
4. ? 事件監聽編碼和發布向導
5. ? 事件監聽的方法和相關的類
事件的分類和 Listener 接口
Servlet 事件有兩個級別:
1. ? Application 級別事件
包含著運行應用程序的虛擬機級別的相關資源和狀態,即和 servlet 的 Context 對象相關。
2. ? Session 級別的事件
包含著一個單一用戶的 session 的一系列請求的相關資源和狀態,即 Http 的 Session 對象。
在上面兩個級別的事件,又可分別分為兩種:
1. ? 生命周期的改變
2. ? 屬性的改變
你可以為上面四種事件創建一個或多個監聽類。一個單一的監聽類可以監視多種事件。
創建一個事件類可以從 javax.servlet 包或 javax.servlet.http 包中實現合適的接口。下表中列出了四種事件相關的接口。
事件種類 |
事件描述 |
接口 |
Context 生命周期的改變 |
context 的建立和即將關閉 context |
Javax.servlet.ServletContextListener |
Context 屬性值的改變 |
添加,刪除,修改 context 的屬性值 |
Javax..servlet.ServletContextAttributeListener |
Session 生命周期的改變 |
Session 的創建,注銷,超時 |
Javax.servlet.http.HttpSessionListener |
Session 屬性值的改變 |
添加,刪除,修改 session 的屬性值 |
Javax.servlet.htpp.HttpSessionAttributeListener |
典型的事件監聽過程
考慮一個 web 應用是由一組訪問數據庫的 servlet 組成的。一個典型的事件監聽機制是這樣的,創建一個 context 生命周期的事件來管理數據庫連接,這個監聽器可以有如下的功能:
1. ? 這個監聽器監視著應用程序的啟動
2. ? 這個應用程序寫入日志到數據庫中并且把連接對象存儲在 context 中
3. ? Servelt 使用連接對象來執行 SQL
4. ? 監聽器監聽應用程序的即將關閉
5. ? 在關閉應用程序之前,先關閉連接對象
事件監聽的聲明和調用
事件監聽的聲明在應用程序的 web.xml 里,用 <listener> 元素,該元素是 <web-app> 的子元素。每個監聽器都對應一個 <listener> ,有一個 <listener-class> 子元素用來指定對應的類名。在每種事件中,你需要指定你想調用的順序。
在應用程序啟動之后,并且在第一次請求之前, servlet 容器會創建并注冊每個監聽類的實例。每種事件,監聽器是按照他們聲明的順序來注冊的。然后,當應用程序開始運行,每種事件監聽器安裝他們的順序調用。在最后一次請求之前,所有的監聽器都保持活動狀態。
一旦應用程序關閉, session 事件首先發生,以他們聲明的順序相反。然后 context 事件發生也是以聲明的順序相反。
下面是一個例子:
<web-app>
?? <display-name>MyListeningApplication</display-name>
?? <listener>
????? <listener-class>com.acme.MyConnectionManager</listenerclass>
?? </listener>
?? <listener>
????? <listener-class>com.acme.MyLoggingModule</listener-class>
?? </listener>
?? <servlet>
????? <display-name>RegistrationServlet</display-name>
????? ...
?? </servlet>
</web-app>
假設 MyConnectionMnanager 和 MyLoggingModule 都是實現 ServletContextListener 接口, MyLoggingModule 也是實現了 HttpSessionListener 接口。
當應用程序運行,兩個監聽器都會監聽 context 生命周期事件, MyLoggingModule 監聽器還會監聽 session 生命周期。在 context 生命周期中, MyConnectionMananger 會首先開始監聽,因為它聲明在前面。
事件監聽器的編碼和發布指南
請注意事件監聽器類的以下規則和指南:
l ???????? 在多線程的應用程序中,屬性可能同時改變。這是不需要 Servlet 容器來同步結果――在這種情況下監聽類本身負責保持數據的完整性。
l ???????? 每個監聽類都必須有一個 public 的零參數的構造函數。
l ???????? 每個監聽類文件必須打包到 WAR 文件,也可以是在 /WEB-INF/classes 或是包含在 /WEB-INF/lib 下的 JAR 文件中。
注意:在分布式的環境中,事件監聽類的作用域是包含這個部署描述文件的虛擬機。不需要分布式的 Web 容器來傳遞 servlet 的 context 事件或是 session 事件到其他的虛擬機。這個在 Sun Microsystem 的 Java Servlet 規范, 2.3 版本。
事件監聽器的方法和相關的類
這部分列出了事件監聽器的方法,當 servlet 的 context 事件或是 servlet 的 session 事件發生時,容器將會調用他們。這些方法的輸入的事件對象的類型不一樣,因此一下討論事件類和他們的方法。
ServletContextListener 方法, ServletContextEvent 類
ServletContextListener 接口規范以下的方法:
?????? void contextInitialized(ServletContextEvent sce)
????????????? servlet 容器調用這個方法來通知監聽器, servlet 的 context 已經建立并且應用程序準備處理請求。
?????? void contextDestory(ServletContextEvent sce)
????????????? servlet 容器調用這個方法來通知監聽器應用程序即將關閉。
Servlet 容器創建一個 java.servlet.ServletContextEvent 對象作為調用 ServletContextListener 方法的輸入。 ServletContextEvent 類包含以下方法,你的監聽器可以調用
ServletContext getServletContext()
用這個方法返回已創建的或是將要銷毀的 servlet context 對象,從中你可以得到你想要的信息。(未完待續)
?
?
?
?
?
?