SpringMVC學(xué)習(xí)筆記 | SpringMVC攔截器詳解:自定義攔截器、攔截器執(zhí)行順序的分析

自定義攔截器

SpringMVC可以使用攔截器對請求進行攔截處理,用戶可以自定義攔截器來實現(xiàn)特定的功能,自定義攔截器必須實現(xiàn)HandlerInterceptor接口

步驟

  • 編寫一個攔截器類,需要實現(xiàn)HandlerInterceptor接口。
    示例:
package com.cerr.springmvc.interceptor;


import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstInterceptor 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");
    }
}

  • 在配置文件中配置該攔截器,使用<mvc:interceptors>來進行配置
    配置示例:
<mvc:interceptors>
        <!-- 配置自定義的攔截器-->
        <bean class="com.cerr.springmvc.interceptor.FirstInterceptor"/>
</mvc:interceptors>

對HandlerInterceptor接口的三個方法的解析

public boolean preHandle(HttpServletRequest httpServletRequest, 
            HttpServletResponse httpServletResponse, Object o){};

該方法在目標(biāo)方法執(zhí)行前被調(diào)用,該方法若返回值為true,則繼續(xù)調(diào)用后續(xù)的攔截器和目標(biāo)方法;若返回值為false,則不會再調(diào)用后續(xù)的攔截器和目標(biāo)方法。
可以考慮做權(quán)限,日志,事務(wù)等等。

public void postHandle(HttpServletRequest httpServletRequest, 
        HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView){};

該方法在目標(biāo)方法執(zhí)行之后、渲染視圖之前被調(diào)用,可以對請求域中的屬性或視圖作出修改。

public void afterCompletion(HttpServletRequest httpServletRequest, 
         HttpServletResponse httpServletResponse, Object o, Exception e){};

該方法在渲染視圖之后被調(diào)用,釋放資源。

攔截器方法執(zhí)行順序圖


從該圖我們可以看出,攔截器先調(diào)的preHandle,然后再去調(diào)目標(biāo)方法,然后再調(diào)postHandle,然后再渲染視圖,最后調(diào)afterCompletion,然后結(jié)束。

關(guān)于攔截器的其他配置

上面中我們說了攔截器可以通過<mvc:interceptors>來配置,而對于這個標(biāo)簽中,里面還有一個子標(biāo)簽我們還沒說到,它就是<mvc:interceptor>。其里面有兩個子標(biāo)簽<mvc:mapping path=""/><mvc:exclude-mapping path=""/>

  • <mvc:mapping path=""/>
    表示該攔截器攔截該請求(path里面的值)
  • <mvc:exclude-mapping path=""/>
    表示該攔截器不攔截該請求(path里面的值)

例如我們配置如下:

<mvc:interceptors>
        <!-- 配置自定義的攔截器-->
        <bean class="com.cerr.springmvc.interceptor.FirstInterceptor"/>

        <mvc:interceptor>
            <mvc:mapping path="/emps"/>
            <bean class="com.cerr.springmvc.interceptor.SecondInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

SecondInterceptor攔截器代碼:

package com.cerr.springmvc.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SecondInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("SecondInterceptor:preHandle");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("SecondInterceptor:postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("SecondInterceptor:afterCompletion");
    }
}

配置后,對于SecondInterceptor攔截器,只攔截emps請求,而emps請求會被FirstInterceptorSecondInterceptor攔截。

運行后訪問emps結(jié)果如下:



紅框為第二個攔截器,綠框為第一個攔截器。

而如果訪問一個其他的(例如i18n)結(jié)果如下:



綠框為第一個攔截器,只被第一個攔截器所攔截。

多個攔截器的攔截方法執(zhí)行順序


從執(zhí)行順序圖我們可以看出,對于preHandle方法,先配置的先執(zhí)行;對于postHandle方法,先配置的后執(zhí)行;對于afterCompletion方法,先配置的后執(zhí)行。

有一點需要注意的是:對于afterCompletion方法是否執(zhí)行是取決于preHandle方法的,在某一個攔截器的prehandle方法返回false前的所有攔截器都會執(zhí)行afterCompletion方法。例如現(xiàn)在有4個攔截器,而第三個攔截器的prehandle返回了false,所以會執(zhí)行afterCompletion方法的攔截器有攔截器1、攔截器2。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容