【SpringMvc】的攔截器

1.SpringMVC的攔截器
SpringMvc處理器攔截器類似於Servlet 開發中的過濾器Filter,用於對處理器進行預處理和後處理。當收到請求時,DispatcherServlet將請求交給處理器映射(HandlerMapping),讓它找出對應請求的HandlerExecutionChain對象。HandlerExecutionChain是一個執行鏈,它包含一個處理該請求的處理器(Handler),同時可以包含若干個對該請求實施攔截的攔截器(HandlerInterceptor)。當HandlerMapping返回HandlerExecutionChain後,DispatcherServlet將請求交給定義在HandlerExecutionChain中的攔截器和處理器一併處理。HandlerExecutionChain是負責處理請求並返回ModelAndView的處理執行鏈,其結構如下圖所示。請求在被Handler執行的前後,鏈中裝配的HandlerInterceptor會實施攔截操作。
這裏寫圖片描述

攔截器代碼編寫,需要實現HandlerInterceptor接口

public class SpringMvcInterceptor implements HandlerInterceptor{

    /**
     * 在請求到達Handler之前,先執行這個前置處理方法。當該方法返回false時,請求直接返回,不會傳遞到鏈中
     * 下一個攔截器,更不會調用處理器鏈末端的Handler中,只有返回true時請求才向鏈中的下一個處理節點傳遞。
     * SpringMvc中的攔截器是鏈式的,可以同時存在多個interceptor,springmvc會根據聲明的前後順序一個
     * 接一個的執行,且所有的interceptor中的preHandle方法都會在。
     */
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        // TODO Auto-generated method stub
        return true;
    }

    /**
     * 在業務處理器處理請求執行完成後,生成視圖之前執行的動作 
     * 可在modelAndView中加入數據,比如當前時間
     */
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        // TODO Auto-generated method stub

    }

    /**
     * 在DispatcherServlet完全處理完請求後被調用,可用於清理資源、可記錄操作日誌等
     * 當有攔截器拋出異常時,會從當前攔截器往回執行所有的攔截器的afterCompletion()
     */
    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // TODO Auto-generated method stub

    }

}

位於處理器鏈末端的是一個Handler,DispactherServlet通過HandlerAdapter適配器對Handler進行封裝,並按統一的適配器接口對Handler處理方法進行調用。

<!-- 配置MVC攔截器 -->
<mvc:interceptors>
    <!-- 使用bean定義一個interceptor,直接定義在mvc:interceptors根下面interceptor
        將攔截所有的請求
     -->
     <bean class="com.springmvc.assess.interceptor.TimeInterceptor" />
    <mvc:interceptor>
        <!-- 定義在mvc:interceptor下面的表示對特定的請求才進行攔截 -->
        <mvc:mapping path="/**" />
        <bean class="com.springmvc.assess.interceptor.SpringMvcInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

可以在SpringMVC.xml中配置多個攔截器,每個攔截器都可以指定一個匹配的映射路徑,以限制攔截器的作用範圍。

  • 攔截器例子
<!-- springmvc.xml配置MVC攔截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <bean class="com.springmvc.assess.interceptor.TimeInterceptor1" />
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <bean class="com.springmvc.assess.interceptor.TimeInterceptor2" />
    </mvc:interceptor>
</mvc:interceptors>

自定義攔截器
public class TimeInterceptor1 extends HandlerInterceptorAdapter {

    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("[TimeInterceptor1_preHandle]"+ "執行開始時間" + sf.format(new Date()));
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("[TimeInterceptor1_postHandle]"+ "執行時間");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("[TimeInterceptor1_afterCompletion]"+ "執行結束時間" + sf.format(new Date()));
    }

}

public class TimeInterceptor2 extends HandlerInterceptorAdapter {

    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("[TimeInterceptor1_preHandle]"+ "執行開始時間" + sf.format(new Date()));
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("[TimeInterceptor1_postHandle]"+ "執行時間");
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("[TimeInterceptor1_afterCompletion]"+ "執行結束時間" + sf.format(new Date()));
    }

}

攔截器1放行,攔截器2放行,實現的效果:
這裏寫圖片描述

將攔截器1放行,攔截器2阻止,實現的效果:
這裏寫圖片描述

這裏寫圖片描述

發佈了64 篇原創文章 · 獲贊 10 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章