1. 程式人生 > >過濾器鏈、過濾器鏈呼叫原理與順序、過濾器配置細節、過濾器過濾型別

過濾器鏈、過濾器鏈呼叫原理與順序、過濾器配置細節、過濾器過濾型別

過濾器鏈呼叫原理與順序:

web伺服器根據Filter在web.xml檔案中的註冊順序,決定先呼叫哪個Filter,當第一個Filter的doFilter方法被呼叫時,web伺服器會建立一個代表Filter鏈的FilterChain物件傳遞給該方法。在doFilter方法(放行)中,開發人員如果呼叫了FilterChain物件的doFilter方法,則web伺服器會檢查FilterChain物件中是否還有filter,如果有,則呼叫第2個filter,如果沒有,則呼叫目標資源。

根據在web.xml檔案中的順序還決定呼叫的順序:和<filter-mapping>的配置先後順序有關係.

在開發中:Servlet,Filter,Listener配置先後問題: 一般先配置Listener,再配置Filter,最後配置Servlet.

過濾器鏈程式碼測試:chain.doFilter(req, resp);//放行

AFilter:
public class AFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("開始Afilter");
		chain.doFilter(request, response);
		System.out.println("結束AFilter");
	}

	@Override
	public void destroy() {
		
	}

}

BFilter:
public class BFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("開始Bfilter");
		chain.doFilter(request, response);
		System.out.println("結束BFilter");
	}

	@Override
	public void destroy() {
		
	}

}
CFilter:
public class CFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("開始Cfilter");
		chain.doFilter(request, response);
		System.out.println("結束CFilter");
	}

	@Override
	public void destroy() {
		
	}

}
配置web.xml檔案:
<filter>
 	<filter-name>a</filter-name>
 	<filter-class>cn.itsource._01_filterchain.AFilter</filter-class>
 </filter>
 
 <filter>
 	<filter-name>b</filter-name>
 	<filter-class>cn.itsource._01_filterchain.BFilter</filter-class>
 </filter>
 
 <filter>
 	<filter-name>c</filter-name>
 	<filter-class>cn.itsource._01_filterchain.CFilter</filter-class>
 </filter>
 
 <filter-mapping>
 	<filter-name>a</filter-name>
 	<url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <filter-mapping>
 	<filter-name>b</filter-name>
 	<url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <filter-mapping>
 	<filter-name>c</filter-name>
 	<url-pattern>/*</url-pattern>
 </filter-mapping>

請求的順序:開始Afilter——開始Bfilter——開始Cfilter       響應的順序:結束CFilter——結束BFilter——結束AFilter

上面三個過濾器的執行流程:開始Afilter——開始Bfilter——開始Cfilter——結束CFilter——結束BFilter——結束AFilter



配置路徑的細節:

a.精確攔截指定資源

<url-pattern>/hello</url-pattern>:當前Filter只對/hello這個資源做過濾.

b.攔截所有資源

<url-pattern>/*</url-pattern>:當前Filter對所有的請求做過濾.如字元編碼

c.對部分資源進行攔截(以什麼開頭)

    <url-pattern>/system/*</url-pattern>:當前Filter 對/system/之後的請求做過濾.

     比如:/system/list,/system/edit,/system/delete 如許可權判斷

d.對部分資源進行攔截(以什麼結束)

<url-pattern>*.html</url-pattern>:當前Filter 對字尾是ejf的進行過濾。如假靜態化

過濾器過濾型別選擇:

過濾器預設過濾的型別是:request。要想過濾其它的需要在web.xml中配置

<dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>

Filter預設情況下,就只能對一次請求做過濾.

    <dispatcher>REQUEST</dispatcher>

若需要對請求轉發做過濾:

    <dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>