SpringMVC[7]--拦截器定义与配置

在系统中,经常需要在处理用户请求前后执行一些行为,如“权限检测”和“日志记录”,当然不仅这些,还有在请求的前后添加处理逻辑。
SpringMVC提供了Interceptor拦截器机制,有两种实现的方法:

  1. 实现HandlerInterceptor接口,或者继承实现了该接口的类(如:HandlerInterceptorAdapter)
  2. 实现Spring的WebRequestInterceptor接口,或者继承实现了该接口的类。

1. HadnlerInterceptor接口

1.1 HandlerInterceptor接口源码:
package org.springframework.web.servlet;

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

public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

    void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;

    void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
  • preHandle方法:在Handler方法之前执行,返回false表示拦截请求,不再向下执行。返回true表示放行。(返回true才能执行以下方法这个方法可以对请求进行判断,决定程序是否继续执行,或者进行一些前置初始化操作及对请求做预处理。
  • postHandle方法:在Handler方法之后,返回modelAndView之前执行。由于该方法会在DispatcherServlet进行返回视图渲染之前被调用,所以此方法多用于统一处理返回的视图。例如:将公用的模型数据(例如导航栏菜单)添加到视图,或者根据其他情况指定公用的视图。
  • afterCompletion方法:在执行完Handler之后执行。由于是在Controller方法执行完毕后执行该方法,所以该方法适合进行统一的异常或日志处理操作。
1.2 拦截器配置

实现接口之后,需要在Spring的类加载配置文件中配置才能生效。
有两种配置方式:“针对HandlerMapping配置”和“全局配置”。
针对HandlerMapping配置样例:

<!--拦截器映射器配置-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="interceptors">
        <list>
            <ref bean="hInterceptor1"/>
            <ref bean="hInterceptor2"/>
        </list>
    </property>
</bean>
<bean id="hInterceptor1" class="cn.com.mvc.interceptor.HandlerInterceptorDemo1"/>
<bean id="hInterceptor2" class="cn.com.mvc.interceptor.HandlerInterceptorDemo2"/>
  • 优点:针对具体的处理器映射器进行拦截操作。
  • 缺点:当处理器映射器很多时,配置比较繁琐。
    全局配置
<!--全局拦截器配置-->
<mvc:interceptors>
    <!--多个拦截器顺序执行-->
    <mvc:interceptor>
        <!--/** 表示所有url包括子url路径-->
        <mvc:mapping path="/**"/>
        <bean class="cn.com.mvc.interceptor.HandlerInterceptorDemo1"/>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.com.mvc.interceptor.HandlerInterceptorDemo2"/>
    </mvc:interceptor>
</mvc:interceptors>

2. WebRequestInterceptor接口

HandlerInterceptor主要进行请求前和请求后的拦截,而WebRequestInterceptor接口针对请求的拦截器接口,该接口方法参数中没有response,所以使用该接口只进行请求数据准备和处理。

2.1 WebRequestInterceptor接口源码
package org.springframework.web.context.request;
import org.springframework.ui.ModelMap;
public interface WebRequestInterceptor {
    void preHandle(WebRequest var1) throws Exception;

    void postHandle(WebRequest var1, ModelMap var2) throws Exception;

    void afterCompletion(WebRequest var1, Exception var2) throws Exception;
}

每个方法中都有WebRequest参数,WebRequest的方法定义与HttpServletRequest基本相同。对WebRequest进行的所有操作都讲同步到HttpServletRequest中,然后在当前请求中一直传递。

  • preHandle方法:在Handler方法之前执行。该方法返回值为void,即无返回值。所以该方法主要进行书的前期准备。
    利用WebRequest的setAttribute(name, value, scope)方法,将需要准备的参数放到WebRequest属性中。scope参数类型为Integer,在WebRequest的父层接口RequestAttributes中为它定义了三个常量。
常量名 真实值 释义
SCOPE_REQUEST 0 代表只有在request中可以访问。
SCOPE_SESSION 1 如果环境允许它代表一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。
SCOPE_GLOBAL_SESSION 2 如果环境允许,它代表一个全局共享的session,否则就代表普通的session,并且在该session范围内可以访问
  • postHandle方法:在Handler方法之后,返回modelAndView之前执行。其中有一个数据模型ModelMap,它是Controller处理之后返回的Model对象,可以通过改变ModelMap中的属性来该拜年Controller最终返回的Model模型。
  • afterCompletion方法:在执行完Handler之后执行。若之前的preHandle方法中的WebRequest准备了一些参数,那么这里可以将WebRequest参数中不需要的准备资源释放掉。

WebRequestInterceptor拦截接口与HandlerInceptor有两点区别:

  • HandlerInterceptor接口的preHandle有一个Boolean类型的返回值,而WebRequestInterceptor的preHandle方法没有返回值。
  • HandlerInterceptor是针对请求的整个过程的,接口方法中都含有response参数。而WebRequestInterceptor是针对请求的,接口方法参数中没有response。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容