From Gossip@caterpillar

JSP/Servlet: Listener 與 Event



撰寫過AWT或Swing的Java程式設計人員對於Listener與Event應該並不陌生,實作 Listener的類別可以在特定事件發生時,呼叫特定的方法來對事件進行回應,在編寫JSP/Servlet應用程式時,也有類似的Listener介 面與Event類別,所不同的是在AWT或 Swing中是向特定元件加入Listener,而在JSP/Servlet中則是在web.xml中註冊Listener,由Container在特定 事件發生時呼叫特定的實作Listener類別。

至JSP 2.0/Servlet 2.4為止,共有八個Listener介面,以及六個Event類別。

ServletContextListener介面有兩個必須實作的方法,contextInitialized()與 contextDestroyed(),它們接收ServletContextEvent事件,在Container載入Web應用程式時(例如啟動 Container之後),會呼叫contextInitialized(),而當容器移除Web應用程式時,會呼叫contextDestroyed ()方法。

ServletContextAttributeListener介面有三個必須實作的方法,attributeAdded()、 attributeReplaced()、attributeRemoved(),它們接收ServletContextAttributeEvent事 件,若有物件加入為application(ServletContext)物件的屬性,則會呼叫attributeAdded(),同理在置換屬性與移 除屬性時,會分別呼叫attributeReplaced()、attributeRemoved()。

HttpSessionListener介面有兩個必須實作的方法,sessionCreated()與sessionDestroyed (),它們接收HttpSessionEvent事件,與ServletContextListener介面類似,在session (HttpSession)物件建立或被消滅時,會分別呼叫這兩個方法。

HttpSessionAttributeListener介面有三個必須實作的方法,attributeAdded()、 attributeReplaced()、attributeRemoved(),它們接收HttpSessionBindingEvent事件,與 ServletContextAttributeListener介面類似,若有物件加入為session(HttpSession)物件的屬性,則會呼 叫attributeAdded(),同理在置換屬性與移除屬性時,會分別呼叫attributeReplaced()、 attributeRemoved()。

HttpSessionActivationListener介面有兩個必須實作的方法,sessionDidActivate()與 sessionWillPassivate(),它們接收HttpSessionEvent,Activate與Passivate是用於置換物件的動 作,當session物件為了資源利用或負載平衡等原因而必須暫時儲存至硬碟或其它儲存器時(透過物件序列化),所作的動作稱之為Passivate,而 硬盤或儲存器上的session物件重新載入JVM時所採的動作稱之為Activate,所以容易理解的,sessionDidActivate()與 sessionWillPassivate()分別於Activeate後與將Passivate前呼叫。

ServletRequestListener介面有兩個必須實作的方法,requestInitialized()與 requestDestroyed(),它們接收RequestEvent事件,與ServletContextListener介面類似,在 request(HttpServletRequest)物件建立或被消滅時,會分別呼叫這兩個方法。

ServletRequestAttributeListener介面有三個必須實作的方法,attributeAdded()、 attributeReplaced()、attributeRemoved(),它們接收HttpSessionBindingEvent事件,與 ServletContextAttributeListener介面類似,若有物件加入為request(HttpServletRequest)物件 的屬性,則會呼叫attributeAdded(),同理在置換屬性與移除屬性時,會分別呼叫attributeReplaced()、 attributeRemoved()。

實作以上這幾個介面的類別,必須在web.xml中向容器註冊,容器才會在對應的事件發生時呼叫對應的類別,例如:
<listener>
    <listener-class>
      demo.servlet.listener.CustomServletContextListener
    </listener-class>

</listener>

另外還有一個HttpSessionBindingListener介面,它使用的方法不同,擁有兩個必須實作的方法, valueBound()與valueUnbound(),接收的參數為HttpSessionBindingEvent,實作 HttpSessionBindingListener介面的類別,其實例如果被加入至session(HttpSession)物件的屬性中,則會呼叫 valueBound(),如果被從session(HttpSession)物件的屬性中移除,則會呼叫valueUnbound(),實作 HttpSessionBindingListener介面的類別不需在web.xml中設定。