servlet——filter
阿新 • • 發佈:2018-12-18
文章目錄
1 概述
Filter是Servlet規範的三大元件之一。顧名思義,就是過濾。可以在請求到達目標資源之前先對請求進行攔截過濾,即對請求進行一些處理;也可以在響應到達客戶端之前先對響應進行攔截過濾,即對響應進行一些處理。採用的責任鏈設計模式
2 生命週期
Filter的生命週期與Servlet的生命週期類似,其主要生命週期階段有四個:Filter物件的建立、Filter物件的初始化、Filter執行doFilter()方法以及最終Filter物件被銷燬。
Filter的整個生命週期過程的執行,均由Web伺服器負責管理。即Filter從建立到銷燬的整個過程中方法的呼叫,都是由Web伺服器負責呼叫執行的,程式設計師無法控制其執行流程。
3 Demo
1註冊filter
<filter>
<filter-name>myFilter</filter-name>
<filter-class>fiter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping >
2 實現Filter介面
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 做某些操作
request.setCharacterEncoding("utf-8");
// 責任鏈的引用
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
4 FilterChain
FilterChain介面類物件是被用於Tomcat等容器提供給開發者從檢視到資源過濾請求的呼叫鏈的物件。過濾器使用過濾器鏈來呼叫鏈中的下一個過濾器,如果正在呼叫的過濾器是鏈中的最後一個,則會直接呼叫鏈末尾端的資源。
5 Filter詳解
5.1 特點
- Filter是單例多執行緒的。
- Filter是在應用被載入時建立並初始化的,這是與Servlet不同的地方。Servlet是在該Servlet被第一次訪問時建立的。Filter與Servlet的共同點是,其無參構造器與init()方法只會執行一次。
- 使用者每提交一次該Filter可以過濾的請求,伺服器就會執行一次doFilter()方法,即doFilter()方法可以被多次執行。
- 當應用被停止時執行destroy()方法,Filter被銷燬,即destroy()方法只會執行一次。
- 由於Filter是單例多執行緒的,所以為了保證其執行緒安全性,一般情況下是不為Filter類定義可修改的成員變數。因為每個執行緒均可修改這個成員變數,會出現執行緒安全問題。
5.2 dispatcher
- 在中還有一個子標籤,用於設定過濾器的請求型別。其有四種取值,REQUEST、FORWARD、INCLUDE、ERROR。
- FORWARD:若請求是由一個Servlet通過RequestDsipatcher的forward()方法所轉發的,那麼這個請求將被值為FORWARD的Filter所攔截。即當前Filter只會攔截由RequestDispatcher的forward()方法所轉發的請求。其他請求均不攔截。
- INCLUDE:當前Fillter只會攔截由RequestDsipatcher的include()方法所轉發的請求。其他請求均不攔截。
- REQUEST:表示當前過濾其只會攔截普通請求,但是對forward和include的跳轉不進行攔截。(預設值)
- ERROR:表示當跳轉到指定的錯誤處理頁面時,這個跳轉請求會被當前過濾器攔截。
5.3 Filter執行原理
- 當某資源的請求到達Web容器時,會先對請求進行解析,使用解析出來的URI作為比較物件,從Map(Map的key為的值,value為Filter例項物件的引用)中查詢是否存在相匹配的key。若存在,那麼讀取其value,即Filter物件的引用,將該引用存入到陣列中。然後繼續向後查詢,直到將該Map查詢完畢。這樣在陣列中就存在按照查詢順序排好序的Filter引用。
- 陣列初始化完畢後,開始按照陣列元素順序進行執行。所以陣列中的Filter全部執行完畢之後,再跳轉到請求的目標資源。(陣列中存放著與請求相匹配的所有Filter)
5.4 說明
- 若Filter為全路徑匹配方式,那麼url-pattern只能寫為/*,而不能夠寫為/。(寫為/,無論是靜態資源,還是動態資源都不起作用)
- 標籤中可以不使用,但需要指定,即當前過濾器攔截的是對指定Servlet的請求。
6 應用
解決中文亂碼問題,過濾敏感詞、安全許可權檢查等
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>