一、攔截器概念
springmvc中的攔截器(interceptor)類似於Servlet中的過濾器(Filter),它主要用於攔截用戶請求並做相應的處理。在實際項目中會經常使用到攔截器,例如在購物網站中通過攔截器可以攔截未登錄的用戶,禁止其購買商品,或者使用它來驗證已登錄用戶是否有相應的操作權限(即權限驗證),記錄請求信息的日志等應用。
所謂攔截器,就是能夠在進行某個操作之前攔截請求,如果請求符合條件就允許在往下執行。比如說,海關就是一個攔截器,他攔截進出口的貨物,如果貨物滿足進出口條件,則放行,否則就攔截,退回處理。
二、攔截器定義和配置使用
在springmvc中要使用攔截器,就需要對攔截器類進行定義和配置,通常攔截器類可以通過兩種方式來定義。
第一種通過實現HandleInterceptor接口,或者繼承HandleInterceptor接口的實現類HandleInterceptorAdapter來定義;
第二種通過實現WebRequestInterceptor接口,或繼承WebRequestInterceptor接口的實現類來定義。
1、攔截器的定義:以實現HandleInterceptor接口為例
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//做一些操作 方法返回類型為布爾值
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//做一些操作
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//做一些操作
}
}
從以上可以看出,自定義的攔截器類實現了HandlerInterceptor接口,並且實現了接口中的三個方法。對這三個方法解釋如下:
(1)、preHandle()方法
該方法會在控制器方法前執行,其返回值表示是否中斷后續操作。當返回值為true時,表示繼續向下執行;當返回值為false時,會中斷后續的所有操作(包括調用下一個攔截器和控制器類中的方法執行等)。
(2)、postHandle()方法
該方法會在控制器方法調用之后,且解析視圖之前執行。可以通過此方法對請求域中的模型和視圖做出進一步的修改。
(3)、afterCompletion()方法
該方法會在整個請求完成,即視圖渲染結束之后執行。可以通過此方法實現一些資源清理、記錄日志信息等工作。
2、攔截器的配置
要使自定義的攔截器類生效,還需要在springmvc的配置文件中進行配置。配置如下所示:
<!-- 配置攔截器 -->
<mvc:interceptors>
<!-- 使用bean直接定義在<mvc:interceptors>下面的Interceptor將攔截所有請求 -->
<bean class="com.config.AllInterceptor"/>
<!-- 攔截器1 -->
<mvc:interceptor>
<!-- 配置攔截器作用的路徑,/**表示攔截所有路徑 -->
<mvc:mapping path="/**"/>
<!-- 配置不需要攔截器作用的路徑 /admin表示放行所有以/admin結尾的路徑 -->
<mvc:exclude-mapping path="/admin"/>
<!-- 定義在<mvc:interceptor>下面的Interceptor,表示對匹配路徑的請求才進行攔截 -->
<bean class="com.config.AdminInterceptor"/>
</mvc:interceptor>
<!-- 攔截器2 -->
<mvc:interceptor>
<mvc:mapping path="/index/**"/>
<bean class="com.config.IndexInterceptor"/>
</mvc:interceptor>
<!-- 后面可以配置多個攔截器-->
</mvc:interceptors>
需要注意的是在進行配置攔截器時,必須按照如上的順序進行配置,否則攔截器將失效。
三、攔截器執行流程
在運行程序時,攔截器的執行是有一定的順序的,該順序與配置文件中所定義的攔截器的順序是相關的。攔截器執行順序有兩種情況,即單個攔截器和多個攔截器的情況,單個攔截器和多個攔截器的執行順序是不一樣的,略有差別。
1、單個攔截器執行流程
當只定義了一個攔截器時,它的執行流程如下圖所示:
對單個攔截器執行流程解釋如下:
從以上圖中可以看出,程序首先會執行攔截器類中的preHandle()方法,如果該方法返回true,則程序會繼續向下執行處理器中的方法,否則程序將不再往下繼續執行。在業務處理器(即控制器Controller類)處理完請求后,會執行postHandle()方法,然后會通過DispatcherServlet向客戶端返回響應,在DispatcherServlet處理完請求后,才會執行afterCompletion()方法。
因此單個攔截器的執行流程:
prehandle()——Handle(也就是控制器里的方法)——postHandle()——afterCompletion()。
2、多個攔截器執行流程
在大型的企業級項目中,通常會配置多個攔截器來實現不同的功能。例如在springmvc配置文件中配置了兩個攔截器Interceptor1和Interceptor2。配置順序Interceptor1在Interceptor2的前面。
則它們的執行流程如下圖所示:
從以上執行流程圖中可以看出,當有多個攔截器同時工作時,它們的preHandle()方法會按照配置文件中攔截器的配置順序執行,而它們的postHandle()和afterCompletion()方法則會按照配置順序的反序執行。
因此當多個攔截器工作時,其執行流程:
preHandle1——preHandle2——Handle——postHandle2——postHandle1——afterCompletion2——afterCompletion1··········
多個攔截器存在時,其preHandle方法是按次序執行,其余的則是相反順序執行。