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。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容