iT邦幫忙

DAY 19
3

C# Web 開發 跳到 Java Web開發系列 第 16

[Servlet] Listener - 在特定的時候執行程式

  • 分享至 

  • xImage
  •  

上一篇提到Servlet的一個高級特性Filter之後,我們這邊也要來介紹一下另外一個高級特性,那就是Listener。
(和我部落格同時發佈:http://www.dotblogs.com.tw/alantsai/archive/2013/10/11/servlet-listener.aspx
什麽是Listener
Listener和我們在.Net裡面說的Event是差不多的概念。在Asp .net Webform你可以為一個按鈕註冊一個click事件,那麼當按鈕被按了以後,事件裡面的程式碼就會被執行。

Listener是一樣的概念,他有幾個事件可以去被Listen,而只要條件觸發了,那麼裡面的程式碼就會執行。

Listener提供了一種監控機制,讓我們能夠在某些情況發生的時候,執行我們要的程式碼。

什麽能夠被Listen
基本上來說,有三種存放位置被變動以後可以觸發Listener,它們分別是:request,session和Context。

而有兩種情景會被觸發:

1.當存放位置本身在創建和銷毀的時候觸發
2.當存放位置的內容在創建、銷毀和修改的時候觸發。

Listener的基本結構
基本上,Listener都是Interface,而只要有class實作那個Interface,並且註冊到web.xml裡面就可以。

基本Listener是一種廣泛的,意思是只要符合條件的情況下Listener都會被觸發,不過有兩個Listener比較特別,是只作用於實作的那個Class,而那兩個Listener是不需要註冊在web.xml就可以有效的。

存放位置本身在創建和銷毀的時候觸發
總共三個存放位置,而每一個能夠監聽啟動和銷毀的情況,他們都很相似名稱都是xxxListener,xxx代表每一個存放位置,所以就一起介紹。
ServletRequestListener
一樣兩個方法:

1.requestInitialized(ServletRequestEvent ev) - 當request進來的時候會執行
2.requestDestroyed(ServletRequestEvent ev) - 當request處理完要銷毀前執行
這邊需要注意的是,假設request包含在伺服器的圖片,那麼每一個圖片都會觸發requestInitialized()。

HttpSessionListener
此Interface有兩個方法:

1.sessionCreated(HttpSessionEvent ev) - 當Session被建立起來的時候
2.sessionDestroyed(HttpSessionEvent ev) - 當Session time out或者被執行session.invalidate()。基本上就是被銷毀前執行

ServletContextListener
此Interface也是兩個方法:

1.contextInitialized(ServletContextEvent ev) - 當Web container啟動或者部署WAR的時候執行
2.contextDestroyed(ServletContextEvent ev) - 當Web container要停止的時候
當存放內容在創建、銷毀和修改的時候觸發
一樣,結構非常相似,Interface名稱都是xxxAttributeListener。xxx分別代表ServletRequest、HttpSession和ServletContext。

而它們關注是內容變化,因此個自有三個方法,也都是xxxAdded()、xxxReplaced()和xxxRemoved()。xxx分別是:request、session和context。

只Listen有實作的Class
上面的xxxAttributeListener是針對所有只要有動到那三個儲存空間的動作都會被觸發,不過這邊有兩個特別的Listener只會在有實作的Class觸發。

HttpSessionBindingListener
這個有兩個方法,valueBound(HttpSessionBindingEvent ev)和valueUnbound(HttpSessionBindingEvent ev)。

有實作這個interface的class,只要是這個class的object被放入Session(呼叫valueBound())和從Session銷毀(呼叫valueUnbound())都會呼叫對應的方法。

這邊或許有一個問題是,同樣的功能我不是能夠用HttpSessionAttributeListener的sessionAdded()和sessionRemoved()取得嗎?

使用HttpSessionBindingListener的好處是:

1.不需要做type conversion - 因為你知道進來的一定是這個class type
2.如果只是要監控這一個Class,那麼比較方便
當然壞處就是high coupling。

HttpSessionActivationListener
這個其實我還不是很清楚用途。我只知道在Session裡面的物件如果都是Serializable,那麼就不需要擔心,不然的話就要透過這個Listener在sessionWillPassivate( HttpSessionEvent ev)的時候把它存起來,然後再sessionDidActivate(HttpSessionEvent ev)把它讀出來。

好像主要是爲了當Session需要在JVM傳遞的時候用到。
配置Listener
除了那兩個只會影響到有事做Class的Listener之外,其他的Listener都需要在Web.xml裡面註冊。這有個好處,哪天如果不需要了,把註冊的地方從web.xml刪除就沒有作用了。

Listener通常放在Servlet的上面。

註冊格式很簡單:

<listener> 
<listener-class>{fully qualified class name}</listener-class> 
</listener> 

Listener的幾個使用情景
Listener有很多用途,這邊我只舉例幾個常用的。

初始化整個網站使用的參數
還記得我們可以再web.xml利用Context-Param的方式設定預設參數。如果我們網站很常讀取這些內容,可以再Web Container啟動的時候把它們讀進memory裡面,減少之後的IO。

這個時候就會用到ServletContextListener的contextInitialized()來達到。

首先定義一個專門用來裝值的class:

package mine; 
public class Config 
{           
public static String ipAddress;           
public static String port;   
} 

然後定義一個ServletContextListener:

... 
public class ContextInitListener implements ServletContextListener 
{   
@Overridepublic void contextInitialized(ServletContextEvent ev) 
{       
ServletContext context = ev.getServletContext();  
         mine.Config.ipAddress = context.getInitParameter("ipAddress");   
  mine.Config.port = context.getInitParameter("port"); } 
... 

在註冊到web.xml裡面:

<listener>     
<listener-class>listener.ContextInitListener</listener-class> </listener> 

之後在任意頁面都可以取得Config裡面的值。

記錄目前瀏覽人數
我們其實可以透過HttpSessionListener來知道目前瀏覽網站的人數。只要sessionDestroy()表示有人離開,而sessionCreate()表示有人進來。

結語
透過這一篇的介紹,希望對於Listener的使用有比較瞭解。

Filter和Listener的搭配使用讓我們可以達到很多效果,而且這些還是low coupling的方式。假設如果上線了客戶和你說不想要/想要某些功能是需要修改到所有頁面才能做到(例如記錄頁面瀏覽人次),這個時候註冊/反註冊filter或者listener都是非常簡單的,只要修改web.xml裡面就能達到。


上一篇
[Servlet] Filter - 強大的關卡控管人
下一篇
[JSTL] 標準標籤庫的介紹
系列文
C# Web 開發 跳到 Java Web開發27
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言