SpringMVC随笔——认识拦截器

来源:互联网 发布:win10磁盘整理软件 编辑:程序博客网 时间:2024/05/21 07:05

SpringMVC随笔——认识interceptor

1.拦截器简单介绍

1.1 SpringMVC拦截器概述
SpringMVC的拦截器类似于Struts2的拦截器(一般配置在struts.xml文件中,用来动态拦截Action调用的对象),又不同于Servlet的过滤器(一般配置在web.xml文件中,可以用来拦截任何的请求)。SpringMVC拦截器用于对Action请求进行预处理与后处理。

1.2 SpringMVC拦截器与Sturus2拦截器的区别

  • 相同之处:两者都传递了request与response作用域,都是继承servlet的filter过滤器,都是在做一件事情之前拦截请求,做完之后处理请求。
  • 不同之处:Struts2过滤之后是去Action 的,而SpringMVC过滤之后是去找Controller。在SpringMVC中,使用了注解机制(@Controller、@RequestMapping)与扫描包,会自动找到相应的url进行处理。Sturts2有自己的interceptor机制,而SpringMVC则是独立的AOP方式。

2.应用场景

主要用于以下的三个方面:

  • 权限检查:比如登录用户的权限问题,哪些用户登录系统以后只能看到某些菜单页面等。
  • 日志记录:记录请求的日志信息,日后可以做到信息监控与统计等。
  • 性能监控:记录系统性能,用来记录请求经过处理器结束以后的时间段。

3.实现interceptor拦截器

SpringMVC中拦截器的实现比较简单,一般有两种方式:
第一是实现Spring的HandlerInterceptor 接口,或者继承实现了HandlerInterceptor接口的类。
第二是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。

3.1 实现HandlerInterceptor接口
下面是简单的一个Interceptor实现接口HandlerInterceptor的代码示例:

import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;  import org.springframework.web.servlet.HandlerInterceptor;  import org.springframework.web.servlet.ModelAndView;  public class MyInterceptor implements HandlerInterceptor {      @Override      public boolean preHandle(HttpServletRequest request,              HttpServletResponse response, Object handler) throws Exception {          // TODO Auto-generated method stub          return false;      }      @Override      public void postHandle(HttpServletRequest request,              HttpServletResponse response, Object handler,              ModelAndView modelAndView) throws Exception {          // TODO Auto-generated method stub      }      @Override      public void afterCompletion(HttpServletRequest request,              HttpServletResponse response, Object handler, Exception ex)      throws Exception {          // TODO Auto-generated method stub      }  }

由代码可以看出,HandlerInterceptor定义了三个方法,这三个方法就是拦截器主要的构成,通过它们可以实现拦截处理。下面是三个回调方法的介绍:
(1)preHandler:

  • 概述:预处理回调方法(请求处理之前进行调用),是用来对处理器进行预处理的。
  • 功能:首先SpringMVC的拦截器是以链式处理的,也就是拦截栈:Interceptor1—>Interceptor2–>…–>InterceptorN–>Controlle–>InterceptorN–>Interceptor2–>…–>Interceptor1。一开始最先执行的肯定是Interceptor1的preHandler方法,故preHandler可以有两个方面的作用:第一就是进行前置初始化的操作,还有对请求进行预处理。第二就是方法的返回类型为boolean,当为返回值为true是表示请求要进行下去,继续调用后面的Intreceptor的preHandler方法,当为false时,表示请求结束,后面的Controller与Interceptor不再执行。

(2)postHandler:

  • 概述:后处理回调方法,实现处理器的后处理(也就是在Controller调用方法之后执行,但会在DispatcherServlet进行视图返回渲染之前被调用)
  • 功能:首先在preHandler的返回值为true的情况下才能继续,其主要的功能是:在Controller处理之后我们可以对ModelAndView(ModelAndView介绍)的对象进行操作。

(3)afterCompletion:

  • 概述:整个请求过程完毕回调方法(也就是在视图渲染完毕之后回调)
  • 功能:同理,preHandler返回值为true才能执行,其主要的功能就是:在整个请求结束之后,我们可以进行一些资源的清理操作,或者性能的监控操作,比如,在结束之后,我们要对该请求的结束时间进行记录并输出消耗的时间,其实就是类似与Java中的try-catch-finally中的最后finally资源回收操作。

3.2实现 WebRequestInterceptor

    import org.springframework.ui.ModelMap;      import org.springframework.web.context.request.WebRequest;      import org.springframework.web.context.request.WebRequestInterceptor;      public class AllInterceptor implements WebRequestInterceptor {        /**       *该方法主要用来准备资源数据的       *WebRequest用于存放请求的一些相关属性       */        @Override          public void preHandle(WebRequest request) throws Exception {              //1.放到request范围内的,所以只能在当前请求中的request中获取到。            request.setAttribute("request", "request", WebRequest.SCOPE_REQUEST);            //2.这个是放到session范围内的,如果环境允许的话它只能在局部的隔离的会话中访问,否则就是在普通的当前会话中可以访问            request.setAttribute("session", "session", WebRequest.SCOPE_SESSION);            //3.如果环境允许的话,它能在全局共享的会话中访问,否则就是在普通的当前会话中访问              request.setAttribute("globalSession", "globalSession", WebRequest.SCOPE_GLOBAL_SESSION);          }         /**       *该方法主要是在Controller处理之后,视图渲染之前执行       *其中ModelMap就是Controller返回的Model对象。       *可以对map进行操作从而修改返回的Model属性。       */        @Override          public void postHandle(WebRequest request, ModelMap map) throws Exception {              // TODO Auto-generated method stub              for (String key:map.keySet())                  System.out.println(key);         }         /**       *在整个请求结束之后,用于资源的释放       */        @Override          public void afterCompletion(WebRequest request, Exception exception)          throws Exception {              // TODO Auto-generated method stub              System.out.println(exception);          }      }  

这里实现 WebRequestInterceptor 的与实现HandlerInterceptor接口的方法有所不同。下面主要介绍不同之处
(1)preHandler:

这里的preHandler返回的是void类型,就相当于只有前置初始化,进行资源准备工作的作用,已经没有返回boolean进行调用下一个Intreceptor拦截器的preHandler功能。其次,它只有一个参数WebRequest request,利用WebRequest的setAttribute(name,value,scope)方法可以将相应的value值request、session等放到指定的范围内。这里scope参数有三个常量需要注意:

  • SCOPE_REQUEST :它的值是0,代表只有在request 中可以访问。
  • SCOPE_SESSION :它的值是1,如果环境允许的话它代表的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。
  • SCOPE_GLOBAL_SESSION :它的值是2,如果环境允许的话,它代表的是一个全局共享的session,否则就代表普通的session,并且在该session 范围内可以访问。

(2)postHandler:
其功能跟继承HandlerIntercepto接口的方法的功能差不多,但是这里需要注意的两个参数:

  • WebRequest参数是用于传递请求数据的,在preHandler中准备好的数据通过它就可以传递与访问
  • ModelMap 就是Controller 处理之后返回的Model 对象,我们可以通过改变它的属性来改变返回的Model 模型。

(3)afterCompletion:
同样的起到在整个过程结束之后资源清理释放的功能,这里的两个参数:

  • WebRequest 参数在这里可以被释放与清理。
  • Exception参数是当前请求的异常对象。

4.拦截器运行流程图

流程图是以实现HandlerInterceptor接口的拦截器为例的。

这里写图片描述

5.配置拦截器

在spring-mvc.xml文件中配置如下代码:
(1)加入支持MVC的schema代码之后,就可以使用<mvc:interceptors>标签
xml代码如下:

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

(2)使用<mvc:interceptors>标签加入Spring
MVC拦截链中的我们定义好的拦截器

<!--配置拦截器, 多个拦截器,顺序执行 -->  <mvc:interceptors>      <!-- 在mvc:interceptors根下使用bean标签:可以拦截所有的Controller -->      <bean class="com.web.interceptor.AllInterceptor"/>      <mvc:interceptor>         <!--            1.需要拦截的特定路径/interceptorDemo/login.do"           2.匹配的是url路径, 如果不配置或"/**",将拦截所有的Controller           -->         <mvc:mapping path="/interceptorDemo/login.do"/>          <!-- 在mvc:interceptor下面的MyInterceptor表示是对特定的请求才进行拦截的 -->          <bean class="com.web.interceptor.MyInterceptor"/>      </mvc:interceptor>  </mvc:interceptors> 

在标签mvc:interceptors下声明拦截器主要用两种形式:

  • 定义在mvc:interceptors根下使用bean标签,可以拦截所有的请求。
  • 定义在mvc:interceptor标签下,则通过其下的子标签mvc:mapping来定义需要拦截的请求路径。

参考大神们的资料:

SpringMVC中使用Interceptor拦截器:http://elim.iteye.com/blog/1750680
第五章 处理器拦截器详解——跟着开涛学SpringMVC:http://jinnianshilongnian.iteye.com/blog/1670856/
谈一谈struts2和springmvc的拦截器:http://blog.csdn.net/salerzhang/article/details/9713059
SpringMVC拦截器(资源和权限管理):http://blog.csdn.net/tonytfjing/article/details/39207551

原创粉丝点击