SpringMVC随笔——认识拦截器

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接口的拦截器为例的。

SpringMVC随笔——认识拦截器_第1张图片

5.配置拦截器

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

"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)使用标签加入Spring
MVC拦截链中的我们定义好的拦截器

  
<mvc:interceptors>  
      
    <bean class="com.web.interceptor.AllInterceptor"/>  
    <mvc:interceptor> 
         
        <mvc:mapping path="/interceptorDemo/login.do"/>  
          
        <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

你可能感兴趣的:(SpringMVC,spring,mvc,interceptor,拦截器,MVC,新手)