1. 程式人生 > >SpringMVC攔截器配置

SpringMVC攔截器配置

SpringMVC 攔截器

攔截器顧名思義就是用於攔截訪問請求的,我們可以在攔截器裏對訪問請求進行事先的處理,例如權限檢查、記錄日誌、驗證請求數據等等。說白了就是我們可以在請求到控制器之前對其進行一個處理。

攔截器基本上和過濾器是類似的,只不過攔截器提供的方法比較實用,參數也比較多,而且攔截器是受到spring容器的管理的。

實現攔截器很簡單,只需要實現spring裏的HandlerInterceptor接口並實現接口中的三個方法即可,如下示例:

package org.zero01.test;

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

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

public class TestInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("TestInterceptor--攔截器的preHandle方法被執行了");

        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("TestInterceptor--攔截器的postHandle方法被執行了");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("TestInterceptor--攔截器的afterCompletion方法被執行了");
    }
}

註:在springmvc4.x版本中這三個方法都是必須要實現的,而在springmvc5.x版本中則不是必須實現的。

關於這三個方法的執行順序:

  • preHandle方法在請求到控制器之前被執行,也就是預處理方法,該方法的返回值決定請求是否發送到控制器中,true是發送,類似於filter中的doFilter,false則是中斷
  • postHandle方法在控制器之後被執行,此時我們可以通過modelAndView參數對象對模型數據或對視圖數據進行處理
  • afterCompletion方法在整個請求處理完畢時執行,即在視圖渲染完畢時回調,如性能監控中我們可以在此記錄結束時間並輸出消耗時間,還可以進行一些資源的清理

完成攔截器的編寫後,在Spring配置文件中,裝配這個攔截器:

<mvc:interceptors>
    <bean class="org.zero01.test.TestInterceptor"/>
</mvc:interceptors>

然後編寫控制器代碼如下:

package org.zero01.test;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TestController {

    @RequestMapping("/test/test.do")
    public String test(){
        System.out.println("控制器--test方法被執行了");

        return "index";
    }
}

通過瀏覽器訪問後,控制臺打印結果如下:

TestInterceptor--攔截器的preHandle方法被執行了
控制器--test方法被執行了
TestInterceptor--攔截器的postHandle方法被執行了
TestInterceptor--攔截器的afterCompletion方法被執行了

註:攔截器是在DispatcherServlet之後的,如果DispatcherServlet報錯的話,攔截器是不會被執行的。

以上是正常的流程,我們來看看中斷的流程,把preHandle方法中的返回值改成false,如下:

     ...
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("TestInterceptor--攔截器的preHandle方法被執行了");

        return false;
    }
    ...

通過瀏覽器訪問後,控制臺打印結果如下:

TestInterceptor--攔截器的preHandle方法被執行了

從控制臺的打印結果中可以看到,請求沒有被發送到控制器上,而是在攔截器這裏中斷了。

springmvc裏有個&lt;mvc:mapping/&gt;標簽,通過這個標簽我們可以配置攔截器只攔截哪些路徑下的請求:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/test/**"/>
        <bean class="org.zero01.test.TestInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

如上配置,表示指定攔截器只攔截/test/下的所有請求。如果是其他請求則不會觸發攔截器。

除此之外,我們還可以通過&lt;mvc:exclude-mapping/&gt;標簽來指定哪個uri的請求不會被攔截器攔截,例如我們指定了攔截器攔截/test/目錄下的所有請求,但是我希望訪問/test/test.do的請求不被攔截器攔截,則可以使用這個標簽進行配置,如下:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/test/**"/>
        <mvc:exclude-mapping path="/test/test.do"/>
        <bean class="org.zero01.test.TestInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

如上配置,表示訪問/test/test.do的請求不會觸發攔截器。

SpringMVC攔截器配置