Javaweb--Filter

來源:視頻資料,網上博客

一、Filter概述

1.概念

Filter稱之爲過濾器,是用來做一些攔截的任務。客戶端每次向服務器發送資源請求時,都會被Filter攔截,只有當Filter同意請求時,纔可以訪問該資源。

在這裏插入圖片描述

  • 客戶端發送http請求,進入到Filter攔截器中,進行相關業務邏輯
  • 判定通行,進入到Servlet,Servlet執行完畢,又返回Filter,進行一些增強,最後響應回到服務器
  • 判斷不通行,訪問超時
2.一些使用例子

登錄驗證、統一編碼處理、敏感字符過濾等等

二、快速入門

  1. 編寫java類實現Filter接口
  2. 複寫其方法
  3. 配置攔截路徑(使用註解或者是在web.xml中配置)

在web項目中,直接右鍵創建一個Filter,然後複寫裏面的doFilter方法,這裏使用註解的方式

//配置攔截路徑
@WebFilter("/*")
public class Filter implements javax.servlet.Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("訪問前使用了Filter");
        //放行
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

在web.xml中配置

<filter>
    <filter-name>demo1</filter-name>
    <!-- 攔截器全限定類名 -->
    <filter-class>com.Filter.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
    <!-- 攔截路徑 -->
    <url-pattern>/*</url-pattern>
</filter-mapping>

這樣就配置好了一個Filter過濾器

三、Filter的生命週期

我們發現,在要實現Filter類的3個方法,分別是init、doFilter、destroy這和Servlet很相似,這3個方法代表着Filter的生命週期

  • init:在服務器啓動時,會創建Filter對象,這時會調用init方法,這個方法只執行一次,主要是用於加載資源
  • doFilter:每一次請求被攔截資源時,會執行。執行多次
  • destroy:在服務器關閉後,Filter對象被銷燬。如果服務器是正常關閉,則會執行destroy方法。只執行一次。用於釋放資源

四、過濾器執行過程分析

​ 當配置好過濾器,並且配置好需要攔截的資源目錄後(注意:這裏爲了簡便,說的都是隻有一個攔截器的情況),如果是服務器第一次啓動,那麼調用Filter的init方法,當客戶端訪問服務器的資源時,首先會執行doFilter方法,這個doFilter方法會傳遞一個FilterChain對象,這個對象也有一個doFilter方法,用於判定是否通行。在調用這個方法之前的代碼都是攔截前執行的代碼,這個方法之後的代碼在響應之後會執行,

​ 也就是說chain.doFilter(req, resp);這行代碼就是個分界線,前面的代碼是攔截,後面的代碼是做一些響應時的增強

五、過濾器配置

1.攔截路徑寫法
  • /index.jsp 只有訪問index.jsp資源時,過濾器纔會被執行,也就是攔截具體的資源路徑
  • /user/* 攔截目錄訪問/user下的所有資源時,過濾器都會被執行
  • *.jsp 訪問所有後綴名爲jsp資源時,過濾器都會被執行,後綴名攔截
  • /* 攔截所有資源
2.攔截類型配置

(1)使用註解的方式

使用註解的方式配置的是dispatcherTypes值

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebFilter {
    String description() default "";

    String displayName() default "";

    WebInitParam[] initParams() default {};

    String filterName() default "";

    String smallIcon() default "";

    String largeIcon() default "";

    String[] servletNames() default {};

    String[] value() default {};

    String[] urlPatterns() default {};

    DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};

    boolean asyncSupported() default false;
}

public enum DispatcherType {
    FORWARD,
    INCLUDE,
    REQUEST,
    ASYNC,
    ERROR;

    private DispatcherType() {
    }
}

可以看到dispatcherTypes的默認值是REQUEST,值得是瀏覽器直接請求資源。DispatcherType是一個枚舉類型,其值爲:

  • FORWARD:轉發訪問資源
  • INCLUDE:包含訪問資源
  • ERROR:錯誤跳轉資源
  • ASYNC:異步訪問資源
  • REQUEST:默認值。瀏覽器直接請求資源

(2)web.xml配置
設置dispatcher標籤即可

六、配置多個過濾器

filter是支持配置多個過濾器的,只要該類i實現了過濾器的接口 javax.servlet.Filter就會被認爲是一個過濾器。那麼這裏涉及到一個過濾器鏈執行的先後順序問題,哪一個過濾器先執行,哪一個過濾器後執行。

當然如果過濾器的執行順序確定了,那麼請求和響應時過濾器執行的順序應該時剛好相反的,例如:

過濾器1
過濾器2
資源執行
過濾器2
過濾器1 

對於不同的配置,有不同的判定先後順序的方法:

(1) 註解:按照類名的字符串比較規則比較,值小的先執行

(2) xml配置:filter-mapping誰定義在上邊,誰先執行

(3)即有註解,又有xml配置:那麼會優先執行web.xml中配置的Filter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章