开发者社区> 无信不立> 正文

springMVC的拦截器

简介: SpringMVC中的Interceptor拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306那样子判断当前时间是否是购票时间。
+关注继续查看

SpringMVC中的Interceptor拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306那样子判断当前时间是否是购票时间。


   一、定义Interceptor实现类


   SpringMVC中的Interceptor拦截请求是通过HandlerInterceptor来实现的。在SpringMVC中定义一个Interceptor非常简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了Spring的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter ;第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。


   (一)实现HandlerInterceptor接口


   HandlerInterceptor接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。

   (1)preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)方法,顾名思义,该方法将在请求处理之前进行调用。SpringMVC中的Interceptor是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor中的preHandle方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean类型的,当它返回为false时,表示请求结束,后续的Interceptor和Controller都不会再执行;当返回值为true时就会继续调用下一个Interceptor的preHandle方法,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法。

   (2)postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法,由preHandle方法的解释我们知道这个方法包括后面要说到的afterCompletion方法都只能是在当前所属的Interceptor的preHandle方法的返回值为true时才能被调用。postHandle方法,顾名思义就是在当前请求进行处理之后,也就是Controller方法调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作。postHandle方法被调用的方向跟preHandle是相反的,也就是说先声明的Interceptor的postHandle方法反而会后执行,这和Struts2里面的Interceptor的执行过程有点类型。Struts2里面的Interceptor的执行过程也是链式的,只是在Struts2里面需要手动调用ActionInvocation的invoke方法来触发对下一个Interceptor或者是Action的调用,然后每一个Interceptor中在invoke方法调用之前的内容都是按照声明顺序执行的,而invoke方法之后的内容就是反向的。

   (3)afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法,该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。

(二)实现WebRequestInterceptor接口


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

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

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

MyInterceptor.java

 1 package com.tgb.interceptor;
 2 
 3 import java.util.List;
 4 
 5 import javax.servlet.http.HttpServletRequest;
 6 import javax.servlet.http.HttpServletResponse;
 7 
 8 
 9 import org.springframework.web.servlet.HandlerInterceptor;
10 import org.springframework.web.servlet.ModelAndView;
11 
12 import com.tgb.entity.Student;
13 /**
14  * 自定义springmvc的拦截器
15 * @ClassName: MyInterceptor 
16 * @Description: TODO(这里用一句话描述这个类的作用) 
17 * @author 尚晓飞
18 * @date 2014-11-3 上午11:07:07 
19 *
20  */
21 public class MyInterceptor implements HandlerInterceptor{
22 
23     private List<String> allowsUrl;//可以再xml配置的时候进行赋值
24     
25     // afterCompletion()方法在DispatcherServlet完全处理完请求后被调用
26     //afterCompletion():这个方法在DispatcherServlet完全处理完请求后被调用,
27     //可以在该方法中进行一些资源清理的操作。
28     @Override
29     public void afterCompletion(HttpServletRequest arg0,
30             HttpServletResponse arg1, Object arg2, Exception arg3)
31             throws Exception {
32         System.out.println("MyInterceptor.afterCompletion(DispatcherServlet完全处理完请求后被调用)");
33         
34         
35     }
36 
37     //业务处理请求之后被调用(preHandle此方法返回false,该方法不执行)
38     //postHandle():这个方法在业务处理器处理完请求后,被调用。该方法执行是,jsp等视图还没有渲染。
39     //在该方法中对用户请求request进行处理。
40     @Override
41     public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
42             Object arg2, ModelAndView arg3) throws Exception {
43         System.out.println("MyInterceptor.postHandle(业务处理请求之后被调用)");
44         
45     }
46 
47     //业务处理请求之前被调用
48     //preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request进行处理。
49     //如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;
50     //如果程序员决定不需要再调用其他的组件去处理请求,则返回false。
51     @Override
52     public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
53             Object arg2) throws Exception {
54         String uri=arg0.getRequestURI();
55         String url=arg0.getRequestURL().toString();
56         System.out.println("MyInterceptor.preHandle(业务处理请求之前被调用)");
57         System.out.println("MyInterceptor.preHandle(第一个拦截器:uri)"+uri);
58         System.out.println("MyInterceptor.preHandle(第一个拦截器:url)"+url);
59         
60         //进行拦截的地址,可以对url进行重定向
61         //获取session
62         Student student=(Student) arg0.getSession().getAttribute("student");
63         if(student==null){
64             //用户未登录或者正在登录。但拦截器已经过滤了登录url的请求。因此为虽已经登录,但session死亡
65             arg0.getSession().setAttribute("msg", "长时间未操作,请重新登录");
66             //重定向
67             arg1.sendRedirect("/test_ssh/login.jsp");
68             //请求转发
69             //arg0.getRequestDispatcher("/test_ssh/login.jsp").forward(arg0, arg1);
70             
71         }
72         return true;
73     }
74 
75     public List<String> getAllowsUrl() {
76         return allowsUrl;
77     }
78 
79     public void setAllowsUrl(List<String> allowsUrl) {
80         this.allowsUrl = allowsUrl;
81     }
82 
83     
84     
85 }
View Code

拦截器的配置。在配置控制器的xml中配置。spring-mvc.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:mvc="http://www.springframework.org/schema/mvc"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 7     http://www.springframework.org/schema/beans/spring-beans.xsd
 8     http://www.springframework.org/schema/context
 9     http://www.springframework.org/schema/context/spring-context-3.2.xsd
10     http://www.springframework.org/schema/mvc
11     http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
12     
13     <!--此xml是springMvc是启动控制器和视图解析工具的 -->
14     
15     <!-- 注解扫描包 pojo处定义@Controller,此配置扫描相应的类包,将有注解的pojo变成一个可以分发http请求的控制器-->
16     <!-- @Controller将pojo变成可以分发http请求的控制器。 -->
17     <!-- @RequestMapping确定不同请求,调用不同控制器中的某个控制器,然后调用某个控制器中的某个方法 -->
18     <!-- 类头定义@RequestMapping是提供初步的请求映射信息(相对于项目部署),方法头定义@RequestMapping(相对于类头部署)是确定请求所要调用的方法。请求规则包含:url,请求参数,请求方法,请求头 -->
19     <context:component-scan base-package="com.tgb.web" />
20     
21     <!-- <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案。<mvc:annotation-driven /> 
22             会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。
23             并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。
24            后面,我们处理响应ajax请求时,就使用到了对json的支持。后面,对action写JUnit单元测试时,要从spring IOC容器中取DefaultAnnotationHandlerMapping
25            与AnnotationMethodHandlerAdapter 两个bean,来完成测试,取的时候要知道是<mvc:annotation-driven />这一句注册的这两个bean。-->
26     <mvc:annotation-driven />
27     
28     
29     <!-- 静态资源(js/image)的访问 -->
30     <mvc:resources location="/js/" mapping="/js/**"/>
31     
32     
33     <!-- 定义视图解析器 -->    
34     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
35         <property name="prefix" value="/"></property>
36         <property name="suffix" value=".jsp"></property>
37     </bean>
38     
39     <!-- 配置springMVC拦截器 。内部可以配置多个拦截器。一个拦截器是一个<mvc:interceptor></mvc:interceptor>节点。执行顺序,根据配置的上下顺序-->
40     <mvc:interceptors>
41         <!-- 第一个拦截器 -->
42         <mvc:interceptor>
43             <!-- 凡是请求路径符合/*/*都被该拦截器拦截 -->
44             <mvc:mapping path="/*/*"/>
45             <!-- 可以指定对某些请求地址不进行拦截 -->
46             <mvc:exclude-mapping path="/student/findAll"/>
47             <!-- 自定义拦截器的java类。 -->
48             <bean class="com.tgb.interceptor.MyInterceptor">
49                 <property name="allowsUrl"><!-- 自定义拦截器类中的一个list属性。以下为该list属性赋值 。此处做判断,表示不拦截的url-->
50                     <list>
51                         <value>/js</value>
52                         <value>/css</value>
53                         <value>/images</value>
54                     </list>
55                 </property>
56             </bean>
57         </mvc:interceptor>
58     </mvc:interceptors>
59 </beans>
View Code

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Spring MVC 中“拦截器”处理模型数据 (二) @ModelAttribute
在这里强烈建议看看我之前写的几篇关于SpringMVC的博客,都是串通的。 @ModelAttribute这个是SpringMVC中处理模型数据的最难也是最重要的点。相当于以前Struct的拦截器。 用途:比如我们要修改一个对象的部分数据,按照以前的思维,new一个对象保存数据,然后赋值,把不修改数据先拿出来保存起来。但是这个已经Out了, 在SpringMVC中,是拿到
2067 0
spring中的拦截器
java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截然后再之前或者之后加入某些操作.
29 0
Spring MVC interceptor拦截指定后缀请求
今天想拦截所有的json请求,找了一圈没找到解决方案,偶然看到stackoverflow上面的回复,才解决了这个难题。 特贴出来共享。 直接在xml文件中配置即可: &lt;mvc:interceptors&gt; &lt;mvc:interceptor&gt; &lt;mvc:mapping path="/**/*.json" /&gt; &lt;!-- 定义在m
3264 0
SpringMVC 拦截器 筛选
     如果只配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,但是如果配置拦截了所有的请求(如我们上面配置的“/”),就会造成js文件、css文件、图片文件等静态资源无法访问 一般Web应用服务器默认的Servlet名称是"default",所以这里我们激活...
743 0
Spring MVC使用拦截器实现权限控制
1、首先准备对应的架包 2、看看项目的架构 3、基本的web.xml文件 shiro SpringMVC org.
992 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
19976 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
27698 0
SpringBoot前后分离项目实现自定义登录拦截
版权声明:本文首发 http://asing1elife.com ,转载请注明出处。 https://blog.csdn.net/asing1elife/article/details/82696896 ...
1825 0
Spring Boot 自动加载指定包下的拦截器
Spring Boot 在我们需要对程序添加拦截器需要使用 WebMvcConfigurerAdapter 中的 addInterceptors方法去注册拦截器,这样我们如果在程序里面有多个拦截或者我们在项目结构为maven 关系存在父子级关系时候。WebMvcConfigurerAdapter 类我们写在父类 这样就无法获取到子类存在哪些拦截器了。这个我们就需要在父级和子级
1986 0
自定义 spring mvc 拦截器(近期项目需求实现)
          需求背景:特定文件夹下任何文件不经过登录,全部拦截强制跳转登录,并客户端禁止下载服务器定制文件夹文件           经过1天多时间的各种尝试,自定义式的强大拦截器实现了,废话不说了,直接贴代码啦。    demo:       1&gt;   根目录下 index.html 内容:               &lt;a href="html/inde
1462 0
+关注
无信不立
人无信不立,业不勤不精
595
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载