1. 程式人生 > >過濾器/攔截器/監聽器 —— Filter、Interceptor、Listener

過濾器/攔截器/監聽器 —— Filter、Interceptor、Listener

在服務器 jsp ext resp 應用 改變 每次 常用 fff

一、Filter的功能

filter功能,它使用戶可以改變一個 request和修改一個response. Filter 不是一個servlet,它不能產生一個response,它能夠在一個request到達servlet之前預處理request,也可以在離開 servlet時處理response.換種說法,filter其實是一個”servlet chaining”(servlet 鏈).

一個Filter包括:

1)在servlet被調用之前截獲;

2)在servlet被調用之前檢查servlet request;

3)根據需要修改request頭和request數據;

4)根據需要修改response頭和response數據;

5)在servlet被調用之後截獲.

服務器每次只調用setFilterConfig方法一次準備filter 的處理;調用doFilter方法多次以處理不同的請求.FilterConfig接口有方法可以找到filter名字及初始化參數信息.服務器可以設置 FilterConfig為空來指明filter已經終結。

每一個filter從doFilter()方法中得到當前的request及response.在這個方法裏,可以進行任何的針對request及 response的操作.(包括收集數據,包裝數據等).filter調用chain.doFilter()方法把控制權交給下一個filter.一個 filter在doFilter()方法中結束.如果一個filter想停止request處理而獲得對response的完全的控制,那它可以不調用下一個filter

例子:

首先新建一個Filter

public class LogFilter implements Filter {  
    private FilterConfig filterConfig;  
    public FilterConfig getFilterConfig() {  
        System.err.println("...getFilterConfig...");  
        return filterConfig;  
    }  
    public void setFilterConfig(FilterConfig filterConfig) {  
        System.err.println(
"...setFilterConfig..."); this.filterConfig = filterConfig; } @Override public void destroy() { System.err.println("...filter destroy..."); } @Override public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { System.err.println("...doFilter..."); chain.doFilter(request, response);//看到這沒,這只要是傳遞下一個Filter } @Override public void init(FilterConfig filterConfig) throws ServletException { System.err.println("...init Filter..."); this.filterConfig = filterConfig; } }

在web.xml裏配置

<filter>  
    <filter-name>LogFilter</filter-name>  
    <filter-class>com.ee.filter.LogFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>LogFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping> 

啟動運行

可以看到...init Filter...首先在TOMCAT啟動時即被打印,然後在運行裏面再看到...doFilter...被打印。

二、Listener功能

它是基於觀察者模式設計的,Listener 的設計對開發 Servlet 應用程序提供了一種快捷的手段,能夠方便的從另一個縱向維度控制程序和數據。目前 Servlet 中提供了 5 種兩類事件的觀察者接口,它們分別是:

4 個 EventListeners 類型的,ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener ;

2 個 LifecycleListeners 類型的,ServletContextListener、HttpSessionListener。

Listener是Servlet的監聽器,它可以監聽客戶端的請求、服務端的操作等。通過監聽器,可以自動激發一些操作,比如監聽在線的用戶的數量。

常用的監聽接口有以下幾個:

1、ServletContextAttributeListener監聽對ServletContext屬性(增/刪/改)的操作。

2、ServletContextListener監聽ServletContext的操作:

  • 當創建ServletContext時,激發contextInitialized(ServletContextEvent sce)方法;
  • 當銷毀ServletContext時,激發contextDestroyed(ServletContextEvent sce)方法。

3、HttpSessionListener監聽HttpSession的操作:

  • 當創建一個Session時,激發session Created(HttpSessionEvent se)方法(這樣就可以給在線人數+1);
  • 當銷毀一個Session時,激發sessionDestroyed (HttpSessionEvent se)方法。

4、HttpSessionAttributeListener監聽HttpSession中的屬性的操作。

  • 當在Session增加一個屬性時,激發attributeAdded(HttpSessionBindingEvent se) 方法;
  • 當在Session刪除一個屬性時,激發attributeRemoved(HttpSessionBindingEvent se)方法;
  • 當在Session屬性被重新設置時,激發attributeReplaced(HttpSessionBindingEvent se) 方法。

下面我們開發一個具體的例子,這個監聽器能夠統計在線的人數。在ServletContext初始化和銷毀時,在服務器控制臺打印對應的信息。當ServletContext裏的屬性增加、改變、刪除時,在服務器控制臺打印對應的信息。

要獲得以上的功能,監聽器必須實現以下3個接口:

  • HttpSessionListener
  • ServletContextListener
  • ServletContextAttributeListener

例子:

public class OnlineUserListener implements HttpSessionListener, ServletContextListener, ServletContextAttributeListener {  
    private long onlineUserCount = 0;  
    public long getOnlineUserCount() {  
        return onlineUserCount;  
    }  
    @Override  
    public void attributeAdded(ServletContextAttributeEvent arg0) {  

    }  
    @Override  
    public void attributeRemoved(ServletContextAttributeEvent arg0) {  

    }  
    @Override  
    public void attributeReplaced(ServletContextAttributeEvent attributeEvent) {  
        System.err.println("...attributeReplaced...");  
    }  
    @Override  
    public void contextDestroyed(ServletContextEvent arg0) {  

    }  
    @Override  
    public void contextInitialized(ServletContextEvent arg0) {  

    }  
    @Override  
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {  
        onlineUserCount ++;  
        toUpdateCount(httpSessionEvent);  
    }  
    @Override  
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {  
        onlineUserCount --;  
        toUpdateCount(httpSessionEvent);  
    }  
    private void toUpdateCount(HttpSessionEvent httpSessionEvent){  
        httpSessionEvent.getSession().setAttribute("onlineUserCount", onlineUserCount);  
    }  
}

Web.xml

<listener>
    <listener-class>com.ee.listener.OnlineUserListener</listener-class>  
</listener>

JSP頁面:

<html>  
    <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
        <title>主頁</title>  
    </head>  
    <body>  
        <h4>你好!</h4>  
        在線人數:<h1><%=request.getSession().getAttribute("onlineUserCount") %></h1>  
    </body>  
</html> 

過濾器/攔截器/監聽器 —— Filter、Interceptor、Listener