ssm框架之springMVC攔截器


1攔截器概述

1.1什么是攔截器?

springMVC中的攔截器(Interceptor)類似於servlet中的過濾器(Filter),它主要用於攔截用戶請求並作相應的處理。例如通過攔截器可以進行權限驗證、記錄請求信息的日志、判斷用戶是否登錄等。

要使用springMVC中的攔截器,就需要對攔截器類進行定義和配置。通常攔截器類可以通過兩種方式 來定義。

1通過實現HandlerInterceptor接口,或繼承HandlerInterceptor接口的實現類來定義.

2通過實現WebRequestInterceptor接口,或繼承WebRequestInterceptor接口的實現類來定義。

以實現HandlerInterceptor接口方式為例,自定義攔截器類的代碼如下:

public class CustomInterceptor implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)throws Exception {
return false;
}
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {

}
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler,
Exception ex) throws Exception {
}
}
 

上述代碼中,自定義攔截器實現了HandlerInterceptor接口,並實現了接口中的三個方法:

preHandle()方法:該方法會在控制器方法前執行,其返回值表示是否中斷后續操作。當其返回值為true時,表示繼續向下執行;當其返回值為false時,會中斷后續的所有操作(包括調用下一個攔截器和控制器類中的方法執行等)。

postHandle()方法:該方法會在控制器方法調用之后,且解析視圖之前執行。可以通過此方法對模型和視圖作出進一步的修改。

afterCompletion()方法:該方法會在整個請求完成,即視圖渲染結束之后執行,可以通過此方法實現一些資源清理、記錄日志信息等工作。

1.2攔截器的配置

開發攔截器就像開發servlet或者filter一樣,都需要在配置文件中進行配置,配置代碼如下:

<!--配置攔截器-->
<mvc:interceptors>
<!--<bean class="com.ma.interceptor.CustomeInterceptor" />-->
<!--攔截器1-->
<mvc:interceptor>
<!--配置攔截器的作用路徑-->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path=""/>
<!--定義在<mvc:interceptor>下面的表示匹配指定路徑的請求才進行攔截-->
<bean class="com.ma.interceptor.Intercptor1"/>
</mvc:interceptor>
<!--攔截器2-->
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean class="com.ma.interceptor.Interceptor2"/>
</mvc:interceptor>
 

上面的代碼中,<mvc:interceptors>元素用於配置一組攔截器,其子元素<bean>中定義的是全局攔截器,它會攔截所有的請求;而<mvc:interceptor>元素中定義的是指定路徑的攔截器,它會對指定路徑下的請求生效。<mvc:interceptor>元素的子元素<mvc:mapping>用於配置攔截器作用的路徑,該路徑在其屬性path中定義。如上述代碼中path的屬性值/**表示攔截所有路徑,“/hello”表示攔截所有以“/hello”結尾的路徑。如果在請求路徑中包含不需要攔截的內容,還可以通過<mvc:exclude-mapping>元素進行配置。

注意:<mvc:interceptor>中的子元素必須按照上述代碼中的配置順序邊寫,即<mvc:mapping><mvc:exclude-mapping><bean>,否則文件會報錯。

2.攔截器的執行流程

2.1單個攔截器的執行流程

在運行程序時,攔截器的執行是有一定順序的,該順序與配置文件中所定義的攔截器的順序相關。

每個攔截器,在程序中的執行流程如下圖所示:

 

 

 

 1.程序先執行preHandle()方法,如果該方法的返回值為true,則程序會繼續向下執行處理器中的方法,否則將不再向下執行。

2.在業務處理器(即控制器Controller類)處理完請求后,會執行postHandle()方法,然后會通過DispatcherServlet向客戶端返回響應。

3.在DispatcherServlet處理完請求后,才會執行afterCompletion()方法。

測試案例:

通過一個測試程序來驗證它的執行流程。

新建一個web項目,准備好springmvc程序運行所需要的jar包,在web.xml中配置前端過濾器和初始化加載信息。

新建一個測試controller,代碼如下:

/**
 * @author mz
 * @version V1.0
 * @Description: 攔截器測試
 */
@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String Hello() {
        System.out.println("Hello!");
        return "success";
    }
}

然后新建一個攔截器,實現HandlerInterceptor接口,並實現其中的方法。

/**
 * @author mz
 * @version V1.0
 * @Description: 實現了HandlerInterceptor接口的自定義攔截器類
 */
public class CustomeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
            throws Exception {
        System.out.println("CustomInterceptor....preHandle");
        //對瀏覽器的請求進行放行處理
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView)
            throws Exception {
        System.out.println("CustomInterceptor....postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e)
            throws Exception {
        System.out.println("CustomInterceptor....afterCompletion");
    }
}

在配置文件中配置攔截器

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <!--定義組件掃描器,指定需要掃描的包-->
    <context:component-scan base-package="com.ma.controller"/>

    <!-- 配置視圖解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--配置攔截器-->
    <mvc:interceptors>
        <bean class="com.ma.interceptor.CustomeInterceptor" />  
    </beans>

把項目發布到Tomcat中,運行測試:

2.2多個攔截器的執行流程

多個攔截器(假設有兩個攔截器interceptor1和interceptor2,並且在配置文件中,interceptor1攔截器配置在前),在程序中的執行流程如下入所示:

 

 從圖可以看出,當有多個攔截器同時工作時,他們的preHandle()方法會按照配置文件中攔截器的順訊執行,而他們的postHandle()方法和afterCompletion()方法則會按照配置順序中的反序執行。

測試案例:

新建兩個攔截器:

/**
 * @author mz
 * @version V1.0
 * @Description: 第一個攔截器
 */
public class Intercptor1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest,
                             HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("Interceptor1....preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor1....postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("Interceptor1....afterCompletion");
    }
/**
 * @author mz
 * @version V1.0
 * @Description: 第二個攔截器
 */
public class Interceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("Interceptor2....preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor2....postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("Interceptor2....afterCompletion");
    }
}

配置信息:

<!--攔截器1-->
        <mvc:interceptor>
            <!--配置攔截器的作用路徑-->
            <mvc:mapping path="/**"/>
            <!--定義在<mvc:interceptor>下面的表示匹配指定路徑的請求才進行攔截-->
            <bean class="com.ma.interceptor.Intercptor1"/>
        </mvc:interceptor>
        <!--攔截器2-->
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean class="com.ma.interceptor.Interceptor2"/>
        </mvc:interceptor>

測試運行:

 

 從結果可以看出,執行的順序和圖片中是一樣的。

如果第一個攔截器return true;而第二個攔截器 return false;結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM