過濾器和攔截器的區別
阿新 • • 發佈:2020-07-23
一、攔截器和過濾器的區別
1、攔截器(Interceptor)只對action請求起作用 即對外訪問路徑
而過濾器(Filter)則可以對幾乎所有的請求都能起作用 包括css js等資原始檔
2、攔截器(Interceptor)是在Servlet和Controller控制器之間執行
而過濾器(Filter)是在請求進入Tomcat容器之後 但是在請求進入Servlet之前執行
在請求結束返回時也是一樣 是在Servlet處理完之後返回給前端之間執行
二、攔截器和過濾器的程式碼實現
1、攔截器
首先需要一個攔截器類並且這個類要實現HandlerInterceptor介面
這個接口裡面有三個方法:
@Overridepublic 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) throwsException { // 在處理過程中(Controller方法處理完之後 DispatcherServlet進行檢視的渲染之前)執行攔截 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在DispatcherServlet進行檢視的渲染後 返回前進行攔截 }
稍微寫一下方法:
1 @Override 2 public booleanpreHandle(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、深度不同