SpringMVC中使用Interceptor拦截器

来源:互联网 发布:上海数据港 曾犁 编辑:程序博客网 时间:2024/06/06 06:37

(二)实现WebRequestInterceptor 接口

  WebRequestInterceptor 中也定义了三个方法,我们也是通过这三个方法来实现拦截的。这三个方法都传递了同一个参数WebRequest ,那么这个WebRequest 是什么呢?这个WebRequest 是Spring 定义的一个接口,它里面的方法定义都基本跟HttpServletRequest 一样,在WebRequestInterceptor 中对WebRequest 进行的所有操作都将同步到HttpServletRequest 中,然后在当前请求中一直传递。

   (1 )preHandle(WebRequest request) 方法。该方法将在请求处理之前进行调用,也就是说会在Controller 方法调用之前被调用。这个方法跟HandlerInterceptor 中的preHandle 是不同的,主要区别在于该方法的返回值是void ,也就是没有返回值,所以我们一般主要用它来进行资源的准备工作,比如我们在使用Hibernate 的时候可以在这个方法中准备一个Hibernate 的Session 对象,然后利用WebRequest 的setAttribute(name, value, scope) 把它放到WebRequest 的属性中。这里可以说说这个setAttribute 方法的第三个参数scope ,该参数是一个Integer 类型的。在WebRequest 的父层接口RequestAttributes 中对它定义了三个常量:

   SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以访问。

   SCOPE_SESSION :它的值是1 ,如果环境允许的话它代表的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。

   SCOPE_GLOBAL_SESSION :它的值是2 ,如果环境允许的话,它代表的是一个全局共享的session,否则就代表普通的session,并且在该session 范围内可以访问。

   (2 )postHandle(WebRequest request, ModelMap model) 方法。该方法将在请求处理之后,也就是在Controller 方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型ModelMap 来改变数据的展示。该方法有两个参数,WebRequest 对象是用于传递整个请求数据的,比如在preHandle 中准备的数据都可以通过WebRequest 来传递和访问;ModelMap 就是Controller 处理之后返回的Model 对象,我们可以通过改变它的属性来改变返回的Model 模型。

   (3 )afterCompletion(WebRequest request, Exception ex) 方法。该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。所以在该方法中可以进行资源的释放操作。而WebRequest 参数就可以把我们在preHandle 中准备的资源传递到这里进行释放。Exception 参数表示的是当前请求的异常对象,如果在Controller中抛出的异常已经被Spring 的异常处理器给处理了的话,那么这个异常对象就是是null 。

下面是一个简单的代码说明:


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 {          // TODO Auto-generated method stub          System.out.println("AllInterceptor...............................");          request.setAttribute("request", "request", WebRequest.SCOPE_REQUEST);//这个是放到request范围内的,所以只能在当前请求中的request中获取到          request.setAttribute("session", "session", WebRequest.SCOPE_SESSION);//这个是放到session范围内的,如果环境允许的话它只能在局部的隔离的会话中访问,否则就是在普通的当前会话中可以访问          request.setAttribute("globalSession", "globalSession", WebRequest.SCOPE_GLOBAL_SESSION);//如果环境允许的话,它能在全局共享的会话中访问,否则就是在普通的当前会话中访问      }        /**      * 该方法将在Controller执行之后,返回视图之前执行,ModelMap表示请求Controller处理之后返回的Model对象,所以可以在      * 这个方法中修改ModelMap的属性,从而达到改变返回的模型的效果。      */      @Override      public void postHandle(WebRequest request, ModelMap map) throws Exception {          // TODO Auto-generated method stub          for (String key:map.keySet())              System.out.println(key + "-------------------------");;          map.put("name3", "value3");          map.put("name1", "name1");      }        /**      * 该方法将在整个请求完成之后,也就是说在视图渲染之后进行调用,主要用于进行一些资源的释放      */      @Override      public void afterCompletion(WebRequest request, Exception exception)      throws Exception {          // TODO Auto-generated method stub          System.out.println(exception + "-=-=--=--=-=-=-=-=-=-=-=-==-=--=-=-=-=");      }        }  

二、把定义的拦截器类加到SpringMVC的拦截体系中

         1.在SpringMVC的配置文件中加上支持MVC的schema


<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"> 

 这样在SpringMVC的配置文件中就可以使用mvc标签了,mvc标签中有一个mvc:interceptors是用于声明SpringMVC的拦截器的。



     (二)使用mvc:interceptors标签来声明需要加入到SpringMVC拦截器链中的拦截器

<mvc:interceptors>      <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->      <bean class="com.host.app.web.interceptor.AllInterceptor"/>      <mvc:interceptor>          <mvc:mapping path="/test/number.do"/>          <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->          <bean class="com.host.app.web.interceptor.LoginInterceptor"/>      </mvc:interceptor>  </mvc:interceptors>  

 由上面的示例可以看出可以利用mvc:interceptors标签声明一系列的拦截器,然后它们就可以形成一个拦截器链,拦截器的执行顺序是按声明的先后顺序执行的,先声明的拦截器中的preHandle方法会先执行,然而它的postHandle方法和afterCompletion方法却会后执行。

          在mvc:interceptors标签下声明interceptor主要有两种方式:

                    (1)直接定义一个Interceptor实现类的bean对象。使用这种方式声明的Interceptor拦截器将会对所有的请求进行拦截。

                    (2)使用mvc:interceptor标签进行声明。使用这种方式进行声明的Interceptor可以通过mvc:mapping子标签来定义需要进行拦截的请求路径。

          经过上述两步之后,定义的拦截器就会发生作用对特定的请求进行拦截了。



转载自:http://elim.iteye.com/blog/1750680