Filter過濾器簡單入門
文章首發於:https://blog.csdn.net/Sky_QiaoBa_Sum/article/details/105042151
Filter過濾器
與Servlet一樣,Filter也是一門web開發中的三大核心技術之一。
見名知義,過濾器的功能其實很好理解:我允許你通過,你就能通過,不允許你通過,想通過門都沒有,當然想通過還是有辦法的,但是決定權在過濾器,說不定過濾器把你加工一下,你就能達到通過的標準了。
欸,差不多就這個意思。我們之前在編寫Servlet的時候,一遇到中文字元的請求或者響應都忘不了在一開始就加上下面兩句話保證在處理請求,發出響應的過程中編解碼統一,對吧:
//請求亂碼處理 request.setCharacterEncoding("utf-8"); //響應亂碼處理 response.setContentType("text/html;charset=utf-8");
試想,如果有好多好多的Servlet都需要這樣處理,是不是會比較麻煩呢,既然都需要,我完全可以在他們進入Servlet之前對請求進行一波加工,出來之後對響應也進行一波加工,會方便許多。
//可提取為初始化引數,這裡預設utf-8了 private String encode = "utf-8"; public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //全域性響應亂碼解決 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; request.setCharacterEncoding(encode); response.setContentType("text/html;charset="+encode); chain.doFilter(request, response); }
這時候,就可以引出web中的過濾器了:一旦對方訪問的資源路徑正好和url-pattern配置的攔截路徑匹配,就將其request物件攔截,攔截之後可以選擇放行,也可以選擇增加一些小操作,通過過濾器,我們就能完成許多通用的操作,如登入驗證、統一編碼處理等。
Filter介面
所有的自定義都必須實現javax.servlet.Filter
介面,下面是介面中定義的三個方法。
public interface Filter { //web應用載入進容器,Filter物件建立之後,執行init方法初始化,用於載入資源,只執行一次。 void init(FilterConfig var1) throws ServletException; //每次請求或響應被攔截時執行,可執行多次。 void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; //web應用移除容器,伺服器被正常關閉,則執行destroy方法,用於釋放資源,只執行一次。 void destroy(); }
引數詳解
FilterConfig var1
:代表當前Filter在web.xml中的配置資訊物件。
ServletRequest var1
:攔截的請求物件。
ServletResponse var2
:攔截的響應物件。
FilterChain var3
:過濾器鏈,提供doFilter()
方法,放行過濾器。
定義Filter
【方式一】web.xml配置
- 建立一個Filter類,實現
javax.servlet.Filter
介面。
public class FilterDemo1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("FilterDemo1.init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterDemo1.doFilter");
}
@Override
public void destroy() {
System.out.println("FilterDemo1.destroy");
}
}
- 在web.xml中配置。
<filter>
<filter-name>Filter1</filter-name>
<filter-class>com.my.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter1</filter-name>
<url-pattern>/*</url-pattern><!--攔截路徑/*表示攔截所有資源-->
</filter-mapping>
【方式二】註解配置
@WebFilter("/*")
public class FilterDemo1 implements Filter
生命週期
web應用被載入到容器中時,過濾器物件被建立,並執行init方法初始化。
過濾器物件建立之後,一直存在於記憶體中,每攔截一次請求或響應時都會執行doFilter方法。
執行doFilter方法之後,可以選擇對處理結果放行,處理邏輯依據具體情況。
直到web應用被移除容器,Filter物件才會銷燬,在銷燬之前會執行destroy方法。
配置細節
【攔截路徑配置】:
- 具體資源路徑:
/index.jsp
只攔截index.jsp
。 - 攔截目錄:
/demo/*
攔截/demo
目錄下的所有資源。 - 字尾名攔截:
*.jsp
攔截所有後綴名為.jsp
的資源。 - 攔截所有資源:
/*
攔截所有資源。
【攔截方式配置】:
註解設定dispatcherTypes
屬性,如:@WebFilter(value = "/FilterDemo4",dispatcherTypes = DispatcherType.REQUEST)
。
- REQUEST:瀏覽器直接請求資源(預設)
- FORWARD:轉發訪問資源
- INCLUDE:包含訪問資源
- ERROR:錯誤跳轉資源
- ASYNC:非同步訪問資源
web.xml配置
- 設定
<dispatcher></dispatcher>
標籤,如:<dispatcher>REQUEST</dispatcher>
。
過濾器鏈
執行流程
執行順序
【註解配置】
過濾器先後順序,按照類名的字串比較規則比較,值小的先執行,Filter1在Filter2之前執行。
【web.xml】配置
過濾器先後順序由<filter-mapping>
的配置順序決定,先配置的先攔截。