關於 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 物件,從中你可以得到你想要的資訊。(未完待續)