請求事件、傾聽器


與請求相關的傾聽器有四個:ServletRequestListenerServletRequestAttributeListenerAsyncListenerReadListener

如果想要在 ServletRequestHttpServletRequest)物件生成或結束時,作些相對應動作,則可以實作ServletRequestListener

package javax.servlet;

import java.util.EventListener;

public interface ServletRequestListener extends EventListener {
    public default void requestDestroyed (ServletRequestEvent sre) {}
    public default void requestInitialized (ServletRequestEvent sre) {}
}

ServletRequest 物件初始化或結束前,會呼叫 requestInitialized()requestDestroyed() 方法,你可以透過傳入的 ServletRequestEvent 來取得 ServletRequest,以針對請求物件作出相對應的初始化或結束處理動作。

在 Servlet 4.0 中,requestInitialized()requestDestroyed() 都被標示為 default,然而實作方法為空,因此,在實作 ServletRequestListener 時,只要針對感興趣的方法定義就可以了。例如:

package cc.openhome;
...
@WebListener()
public class SomeRequestListener implements ServletRequestListener {
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        // ...
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        //...
    }
}

如果在實作 ServletRequestListener 的類別上標註 @WebListener,則容器在部署應用程式時,會實例化該類別並註冊給應用程式。另一個方式是在 web.xml 下如下設定:

<web-app...>
    ...
    <listener>
        <listener-class>cc.openhome.SomeRequestListener</listener-class>
    </listener>
   ...
<web-app>

與請求物件相關的傾聽器還有 ServletRequestAttributeListener,顧名思義,當你在請求物件中加入屬性、移除屬性或替換屬性時,相對應的 attributeAdded()attributeRemoved()attributeReplaced() 方法就會被呼叫,並分別傳入 ServletRequestAttributeEvent

package javax.servlet;

import java.util.EventListener;

public interface ServletRequestAttributeListener extends EventListener {
    public default void attributeAdded(ServletRequestAttributeEvent srae) {}
    public default void attributeRemoved(ServletRequestAttributeEvent srae) {}
    public default void attributeReplaced(ServletRequestAttributeEvent srae) {}
}

在 Servlet 4.0 中,attributeAdded()attributeRemoved()attributeReplaced() 方法都被標示為 default,然而實作方法為空,因此,在實作 ServletRequestAttributeListener 時,只要針對感興趣的方法定義就可以了。

ServletRequestAttributeEvent 有個 getName() 方法,可以取得屬性設定或移除時指定的名稱,而 getValue() 則可以取得屬性設定或移除時的物件。

如果希望容器在部署應用程式時,實例化實作 ServletRequestAttributeListener 的類別並註冊給應用程式,則同樣也是在實作類別上標註 @WebListener

package cc.openhome;
...
@WebListener()
public class SomeRequestAttrListener
               implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        //...
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        //...
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        //...
    }
}

另一個方式是在 web.xml 中設定:

<web-app...>
    ...
    <listener>
        <listener-class>cc.openhome.SomeRequestAttrListener</listener-class>
    </listener>
   ...
<web-app>

在 Servlet 3.0 中,新增了與非同步請求相關的傾聽器 AsyncListener,這在之後談到非同步處理時還會說明。

在 Servlet 3.1 中,在 ServletInputStream 新增了非阻斷 IO 相關的傾聽器 ReadListener,這在之後談到非阻斷 IO 時還會說明。