一、兩者的區別
1、攔截器
java裏的攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前後執行的代碼,也可以在一個action執行前阻止其執行,同時也提供了一種可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中攔截器用於在某個方法或字段被訪問之前,進行攔截然後在之前或之後加入某些操作。------百度百科
2、過濾器
在Web中稱之爲Filter,通過配置多個過濾器,Web系統可以對所有的Servlet請求進行一層一層的過濾,以完成一些特殊的功能。例如常用的資源訪問權限控制、特殊字符以及敏感詞過濾、響應信息壓縮等功能。
3、區別
1> 攔截器是基於java的反射機制的,而過濾器是基於函數回調。
2> 攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
3> 攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。
4> 攔截器可以訪問action上下文、值棧裏的對象,而過濾器不能訪問。
5> 在action的生命週期中,攔截器可以多次被調用,而過濾器只能在容器初始化時被調用一次。(注:這裏的調用一次,是對於構造函數而言。而doFilter會對匹配的請求做持續的處理。)
6> 攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,所以我們可以在攔截器裏注入一個service,可以調用業務邏輯。
二、兩者的執行順序
網上找了一張整體的流程圖,給出地址:點擊打開原圖片。
之後根據這張圖,我們把過濾器和攔截器,摘出來,畫出一張專一詳解過濾器、攔截器,各函數執行順序的示意圖:
話不多說,都在圖上了,請自行觀摩。
三、過濾器代碼demo
你在web.xml中分別配置firstTestFilter、secondTestFilter兩個過濾器。
<filter>
<filter-name>firstTestFilter</filter-name>
<filter-class>com.demo.Filter.FirstTestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>firstTestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>secondTestFilter</filter-name>
<filter-class>com.demo.Filter.SecondTestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>secondTestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
分別創建FirstTestFilter、SecondTestFilter兩個實現了Filter的過濾器類。
FirstTestFilter類:
package com.demo.Filter;
import javax.servlet.*;
import java.io.IOException;
/**
* @author :xch
* date:Create in 2018/7/16 13:48
* description:
*/
public class FirstTestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
System.out.println("我是第一個Filter,執行filterChain.doFilter(request,response)之前。");
filterChain.doFilter(request,response);
System.out.println("我是第一個Filter,執行filterChain.doFilter(request,response)之後。");
}
@Override
public void destroy() {
}
}
SecondTestFilter類:
package com.demo.Filter;
import javax.servlet.*;
import java.io.IOException;
/**
* @author :xch
* date:Create in 2018/7/16 13:48
* description:
*/
public class SecondTestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
System.out.println("我是第二個Filter,執行filterChain.doFilter(request,response)之前。");
filterChain.doFilter(request,response);
System.out.println("我是第二個Filter,執行filterChain.doFilter(request,response)之後。");
}
@Override
public void destroy() {
}
}
注:chain.doFilter將請求轉發給過濾器鏈的下一個filter , 如果下面沒有filter,那就是你請求的資源。
四、攔截器代碼demo
在spring-mvc的配置文件中配置公共的攔截器:
<mvc:interceptors>
<!-- 對所有請求都攔截,公共攔截器 -->
<bean name="testInterceptor" class="com.demo.interceptor.TestInterceptor" />
</mvc:interceptors>
公共攔截器的實現類TestInterceptor:
package com.demo.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author :xch
* date:Create in 2018/7/16 14:06
* description:
*/
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("我是測試的攔截器函數:preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("我是測試的攔截器函數:postHandle");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("我是測試的攔截器函數:afterCompletion");
}
}
代碼部分結束,我們啓動一下項目,隨便發送一個請求,這個請求接口會打印信息:“我是TestController類函數:test”。
看一下控制檯的打印信息:
打印順序完全正確,也驗證了圖例的正確性。
---------------------------------------------------------------------------不關注我“象話”嗎?
如有疑惑,請評論留言。
如有錯誤,也請評論留言。