1. 程式人生 > 實用技巧 >過濾器和攔截器的區別

過濾器和攔截器的區別

一、攔截器和過濾器的區別

1、攔截器(Interceptor)只對action請求起作用 即對外訪問路徑
而過濾器(Filter)則可以對幾乎所有的請求都能起作用 包括css js等資原始檔
2、攔截器(Interceptor)是在Servlet和Controller控制器之間執行
而過濾器(Filter)是在請求進入Tomcat容器之後 但是在請求進入Servlet之前執行
在請求結束返回時也是一樣 是在Servlet處理完之後返回給前端之間執行

二、攔截器和過濾器的程式碼實現

1、攔截器

首先需要一個攔截器類並且這個類要實現HandlerInterceptor介面
這個接口裡面有三個方法:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在攔截點(Controller方法處理之前)執行攔截 若返回的是false則中斷執行 反之亦然 return false; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws
Exception { // 在處理過程中(Controller方法處理完之後 DispatcherServlet進行檢視的渲染之前)執行攔截 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在DispatcherServlet進行檢視的渲染後 返回前進行攔截 }

稍微寫一下方法:

 1 @Override
 2 public boolean
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 3 { 4 // 在Controller方法處理之前執行攔截 若返回的是false則中斷執行 反之亦然 5 6 // 判斷當前的User是否為空 若不為空則不攔截 7 if (request.getSession().getAttribute("USERINFO")!=null) 8 { 9 return true; 10 } 11 // 進行攔截 返回登入介面 12 response.sendRedirect(request.getContextPath()+"/user/doLogin.do"); 13 return false; 14 }

然後需要去SpringMVC的配置檔案中配置攔截器:

 1 <!-- 配置攔截器 -->
 2 <mvc:interceptors>
 3     <mvc:interceptor>
 4         <!-- 攔截所有的mvc控制器(Controller) -->
 5         <mvc:mapping path="/**"/>
 6         <!-- 放行機制 指定對某個頁面不進行攔截 -->
 7         <!-- 攔截器只對action起作用 因此填入的不是頁面路徑 而是方法 -->
 8         <mvc:exclude-mapping path="/user/doLogin.do"/>
 9         <!-- 指定使用哪個攔截器 -->
10         <bean class="net.zjitc.interceptor.LoginInterceptor"/>
11     </mvc:interceptor>
12 </mvc:interceptors>

如此 當訪問的請求不為/user/doLogin.do會被攔截然後重定向到/user/doLogin.do
但是訪問其它的頁面不會被攔截
想要讓頁面也被攔截?你需要過濾器!

2、過濾器

同理 需要一個過濾器類然後實現javax.servlet.Filter介面
注意Filter的路徑別導錯了 因為有很多同名介面

 1 public class LoginFilter implements Filter {
 2 
 3     @Override
 4     public void init(FilterConfig filterConfig) throws ServletException
 5     {
 6         // 過濾器初始化
 7     }
 8 
 9     @Override
10     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
11     {
12 
13     }
14 
15     @Override
16     public void destroy()
17     {
18         // 過濾器銷燬
19     }
20 }

稍微寫一下方法:

 1 @Override
 2 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
 3 {
 4     // ServletRequest是一個介面 而HttpServletRequest是介面的實現
 5     // 但有些方法是HttpServletRequest獨有的 例如getSession()
 6     // HttpServletRequest介面繼承自ServletRequest介面 增加了和Http相關的方法
 7     // 但是我們可以強制轉換
 8     HttpServletRequest request=(HttpServletRequest)servletRequest;
 9     HttpServletResponse response=(HttpServletResponse)servletResponse;
10 
11     // 若使用者沒有登入
12     if (request.getSession().getAttribute("USERINFO")==null && request.getRequestURI().indexOf("/user/doLogin.do")==-1)
13     {
14         response.sendRedirect(request.getContextPath()+"/user/doLogin.do");
15     }
16     // 若使用者已經登入 則繼續下一個請求(繼續訪問)
17     filterChain.doFilter(request,response);
18 }

然後需去web.xml中配置過濾器:

 1 <!-- 配置自定義的Filter 實現登入控制 -->
 2 <filter>
 3     <filter-name>sessionFilter</filter-name>
 4     <filter-class>net.zjitc.filter.LoginFilter</filter-class>
 5 </filter>
 6 <filter-mapping>
 7     <filter-name>sessionFilter</filter-name>
 8     <!-- 攔截所有的頁面 /斜槓代表在webapp目錄下 -->
 9     <url-pattern>/pages/*</url-pattern>
10     <url-pattern>/css/*</url-pattern>
11     <url-pattern>/img/*</url-pattern>
12     <url-pattern>/failer.jsp</url-pattern>
13 </filter-mapping>

三、總結

攔截器和過濾器其實都是AOP程式設計思想的實現
都可以體現例如許可權的檢查 日誌的記錄等功能
但是有不同之處:
1、使用範圍不同
攔截器既可以用在web層 又可以用在Application和Swing程式中
而filter是Servlet規範規定的 只能用於web程式中
2、規範不同
攔截器是在Spring容器內的 是Spring框架支援的
而filter是Servlet規範規定的 是Servlet容器支援的
3、使用的資源不同
4、深度不同