springmvc攔截器使用和原理理解
與struts2類似,springmvc的攔截器主要作用也是在服務端真正處理請求前後進行一些相關的操作。 例如初始化資源,權限監控,會話設置,菜單獲取,資源清理等。
步驟:
1. 定義攔截器
自定義攔截器一般繼承自HandlerInterceptorAdapter 或者實現 HandlerInterceptor 接口。 實現接口需要實現對應的3中方法,繼承父類只需要實現需要的方法即可。preHandle,postHandle,afterCompletion
public class MyInterceptor extends HandlerInterceptorAdapter { @Override publicView Codeboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { /** * preHandle方法是進行處理器攔截用的,顧名思義,該方法將在Controller處理之前進行調用, * SpringMVC中的Interceptor攔截器是鏈式的,可以同時存在多個Interceptor, * 然後SpringMVC會根據聲明的前後順序一個接一個的執行, * 而且所有的Interceptor中的preHandle方法都會在Controller方法調用之前調用。 * SpringMVC的這種Interceptor鏈式結構也是可以進行中斷的, * 這種中斷方式是令preHandle的返回值為false,當preHandle的返回值為false的時候整個請求就 結束了。 這種方式,如果返回false,一般情況需要重定向或者轉發到其他頁面, 采用request的轉發或者response的重定向即可 */} @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { /** * 這個方法只會在當前這個Interceptor的preHandle方法返回值為true的時候才會執行。 postHandle是進行處理器攔截用的,它的執行時間是在處理器進行處理之 後, 也就是在Controller的方法調用之後執行,但是它會在DispatcherServlet進行視圖的渲染之前執行,也就是說在這個方法中你可以對ModelAndView進行操作。這個方法的鏈式結構跟正常訪問的方向是相反的,也就是說先聲明的Interceptor攔截器該方法反而會後調用,這跟Struts2裏面的攔截器的執行過程有點像,只是Struts2裏面的intercept方法中要手動的調用ActionInvocation的invoke方法,Struts2中調用ActionInvocation的invoke方法就是調用下一個Interceptor或者是調用action,然後要在Interceptor之前調用的內容都寫在調用invoke之前,要在Interceptor之後調用的內容都寫在調用invoke方法之後。 */} @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { /** * 該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執行。 * 該方法將在整個請求完成之後,也就是DispatcherServlet渲染了視圖執行, 這個方法的主要作用是用於清理資源的, */ } }
2. xml文件中配置攔截器
定義好攔截器後,在xml文件中進行聲明和添加過濾規則。
<mvc:interceptors> <!-- 寫在外面,表示攔截所有鏈接 --> <bean id="" class=""/> <mvc:interceptor> <mvc:mapping path="/**" /> <!-- 排除攔截的鏈接 --> <mvc:exclude-mapping path="/static/**" /> <bean class="攔截器java代碼路徑" /> </mvc:interceptor> </mvc:interceptors>View Code
至此,springmvc的簡單使用就是這樣。
3. springmvc原理
SpringMVC的攔截器不同於Spring的攔截器,SpringMVC具有統一的入口DispatcherServlet,所有的請求都通過DispatcherServlet,所有的操作都是通過該servlet進行的順序操作,DispatcherServlet也沒有代理,同時SpringMVC管理的Controller也沒有代理。哪不難想到我們在執行controller之前做某些動作,執行完畢做某些動作,render完成做某些動作,都是servlet在開始便策劃好的。SpringMVC的攔截器對應提供了三個preHandle,postHandle,afterCompletion方法。
4. 攔截器與過濾器的區別
過濾器:依賴於servlet容器。在實現上基於函數回調,可以對幾乎所有請求進行過濾,但是缺點是一個過濾器實例只能在容器初始化時調用一次。使用過濾器的目的是用來做一些過濾操作,獲取我們想要獲取的數據,比如:在過濾器中修改字符編碼;在過濾器中修改HttpServletRequest的一些參數,包括:過濾低俗文字、危險字符等
攔截器:依賴於web框架,在SpringMVC中就是依賴於SpringMVC框架。在實現上基於Java的反射機制,屬於面向切面編程(AOP)的一種運用。由於攔截器是基於web框架的調用,因此可以使用spring的依賴註入(DI)進行一些業務操作,同時一個攔截器實例在一個controller生命周期之內可以多次調用。但是缺點是只能對controller請求進行攔截,對其他的一些比如直接訪問靜態資源的請求則沒辦法進行攔截處理。
附上一張servlet執行順序圖(摘錄):
5. struts2與springmvc攔截器不同之處
struts2的自定義攔截器主要有三個方法:init(),intercept(),destroy()
springmvc自定義攔截器同樣有三個方法:preHandle,postHandle,afterCompletion
struts2三個方法主要區別:
Init方法在攔截器類被創建之後,在對Action鏡像攔截之前調用,相當於一個post-constructor方法,使用這個方法可以給攔截器類做必要的初始話操作。
Destroy方法在攔截器被垃圾回收之前調用,用來回收init方法初始化的資源。
Intercept是攔截器的主要攔截方法,如果需要調用後續的Action或者攔截器,只需要在該方法中調用invocation.invoke()方法即可,在該方法調用的前後可以插入Action調用前後攔截器需要做的方法。如果不需要調用後續的方法,則返回一個String類型的對象即可,例如Action.SUCCESS。
springmvc三個方法主要區別:
略(上面已經講過)
綜上,struts2一般在intercept方法中進行權限或者其他規則校驗,校驗失敗的直接返回失敗result所代表的頁面。而spring進行校驗時一般在preHandle中,校驗失敗則直接轉發或者重定向。
springmvc攔截器使用和原理理解