Spring为我们提供了:

org.springframework.web.servlet.HandlerInterceptor接口,



org.springframework.web.servlet.handler.HandlerInterceptorAdapter适配器,

实现这个接口或继承此类,可以非常方便的实现自己的拦截器。



有以下三个方法:



Action之前执行:



1 public boolean preHandle(HttpServletRequest request,   HttpServletResponse response, Object handler);

生成视图之前执行



1 public void postHandle(HttpServletRequest request,   HttpServletResponse response, Object handler,   ModelAndView modelAndView);

最后执行,可用于释放资源



1 public void afterCompletion(HttpServletRequest request,   HttpServletResponse response, Object handler, Exception ex)

分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)

在preHandle中,可以进行编码、安全控制等处理;

在postHandle中,有机会修改ModelAndView;

在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。

参数中的Object handler是下一个拦截器。



如何使用拦截器?



自定义一个拦截器,要实现HandlerInterceptor接口:



Java代码



1

2

3 public class MyInteceptor implements HandlerInterceptor {          略。。。    }

Spring MVC并没有总的拦截器,不能对所有的请求进行前后拦截。

Spring MVC的拦截器,是属于HandlerMapping级别的,可以有多个HandlerMapping ,每个HandlerMapping可以有自己的拦截器。

当一个请求按Order值从小到大,顺序执行HandlerMapping接口的实现类时,哪一个先有返回,那就可以结束了,后面的HandlerMapping就不走了,本道工序就完成了。就转到下一道工序了。

拦截器会在什么时候执行呢? 一个请求交给一个HandlerMapping时,这个HandlerMapping先找有没有处理器来处理这个请求,如何找到了,就执行拦截器,执行完拦截后,交给目标处理器。

如果没有找到处理器,那么这个拦截器就不会被执行。



在spring MVC的配置文件中配置有三种方法:



方案一,(近似)总拦截器,拦截所有url



Java代码



1

2

3 <mvc:interceptors>       <bean class="com.app.mvc.MyInteceptor" />   </mvc:interceptors>

为什么叫“近似”,前面说了,Spring没有总的拦截器。



<mvc:interceptors/>会为每一 个HandlerMapping,注入一个拦截器。总有一个HandlerMapping是可以找到处理器的,最多也只找到一个处理器,所以这个拦截器总会被执行的。起到了总拦截器的作用。



方案二, (近似) 总拦截器, 拦截匹配的URL。



Xml代码



1

2

3

4

5

6 <mvc:interceptors >       <mvc:interceptor>             <mvc:mapping path="/user/*" /> <!-- /user/*  -->            <bean class="com.mvc.MyInteceptor"></bean>         </mvc:interceptor>     </mvc:interceptors>

就是比 方案一多了一个URL匹配。



方案三,HandlerMappint上的拦截器



Xml代码



1

2

3

4

5

6

7 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">         <property name="interceptors">             <list>                 <bean class="com.mvc.MyInteceptor"></bean>            </list>         </property>        </bean>

如果使用了<mvc:annotation-driven />, 它会自动注册DefaultAnnotationHandlerMapping 与AnnotationMethodHandlerAdapter 这两个bean,所以就没有机会再给它注入interceptors属性,就无法指定拦截器。



当然我们可以通过人工配置上面的两个Bean,不使用 <mvc:annotation-driven />,就可以 给interceptors属性 注入拦截器了。





其实我也不建议使用<mvc:annotation-driven />,而建议手动写配置文件,来替代 <mvc:annotation-driven />,这就控制力就强了。

SpringMVC深入总结--Spring中的拦截器的更多相关文章

  1. (转)spring中的拦截器(HandlerInterceptor+MethodInterceptor)

    1.  过滤器跟拦截器的区别 在说拦截器之前,不得不说一下过滤器,有时候往往被这两个词搞的头大. 其实我们最先接触的就是过滤器,还记得web.xml中配置的<filter>吗~ 你应该知道 ...

  2. SpringMVC中的拦截器、过滤器的区别、处理异常

    1. SpringMVC中的拦截器(Interceptor) 1.1. 作用 拦截器是运行在DispatcherServlet之后,在每个Controller之前的,且运行结果可以选择放行或拦截! 除 ...

  3. Spring MVC中的拦截器Interceptor

    谈谈spring中的拦截器 在web开发中,拦截器是经常用到的功能.它可以帮我们验证是否登陆.预先设置数据以及统计方法的执行效率等等.今天就来详细的谈一下spring中的拦截器.spring中拦截器主 ...

  4. SpringMVC中的拦截器

    1. 自定义拦截器 实现HandlerInterceptor接口 拦截器一: package cn.rodge.ssm.interceptor;import javax.servlet.http.Ht ...

  5. 9.springMVC中的拦截器

    springMVC中的拦截器大概大致可以分为以下几个步骤去学习: 1.自定义一个类实现HandlerInterceptor接口,这里要了解其中几个方法的作用 2.在springMVC的配置文件中添加拦 ...

  6. spring mvc中的拦截器小结 .

    在spring mvc中,拦截器其实比较简单了,下面简单小结并demo下. preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Control ...

  7. 【SpringMVC学习11】SpringMVC中的拦截器

    Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理.本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用 ...

  8. (转)SpringMVC学习(十二)——SpringMVC中的拦截器

    http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...

  9. spring boot中注册拦截器

    拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重 ...

  10. springmvc以及springboot中的拦截器配置

    拦截器两种实现   如果不同的controller中都需要拦截器,不能使用相同的拦截器,因为拦截器不能跨controller,这个时候只能为不同的controller配置不同的拦截器,每一个拦截器只能 ...

随机推荐

  1. Ubuntu+Minio对象存储+pm2进程管理

    Minio是一个go编写的高性能对象存储服务,它兼容Amazon S3 API.无论是静态网站的托管,还是数据存储分析,亦或是数据的备份与恢复等多种场景下,都可以为我们提供解决方案. ubuntu安装 ...

  2. PostgreSQL-查询每个表的大小

    1.查询数据库中单个表的大小(不包含索引) select pg_size_pretty(pg_relation_size('表名')); 2.查询所有表的大小并排序(包含索引) SELECT tabl ...

  3. [JVM]关于swap的理解

    关于swap的理解 概念 swap就是内存交换的意思. 计算机内存分为物理内存和虚拟内存.物理内存就是计算机实际内存的大小:虚拟内存是磁盘空间里开辟出一部分,是虚拟出来的内存空间,所以也叫磁盘缓存. ...

  4. P1405 苦恼的小明 题解

    题目传送门 前置知识 扩展欧拉定理 解法 本题幂塔是有限层的,这里与 luogu P4139 上帝与集合的正确用法 中的无限层幂塔不同,故需要在到达递归边界 \(n+1\) 时进行特殊处理,对于处理 ...

  5. dotnet-cnblog tool 测试案例

    这是测试donet-cnblog工具是否能将正常的Typora图片转换为博客园格式 测试1:本地图片导入 测试2:QQ截图 测试3:url https://pics3.baidu.com/feed/9 ...

  6. NC17247 H、Diff-prime Pairs

    题目链接 题目 题目描述 Eddy has solved lots of problem involving calculating the number of coprime pairs withi ...

  7. Github 使用PAT(Personal Access Token)后的命令行登录

    在Github上启用PAT 命令行下使用git push不能再直接使用用户名密码, 在输入密码的地方需要使用PAT来代替. 具体的创建步骤为 https://docs.github.com/en/gi ...

  8. SQLite 入门教程

    不是 MySQL 用不起,而是 SQLite 更有性价比,绝大多数的 Web 应用 SQLite 都可以满足. SQLite 是一个用 C 语言编写的开源.轻量级.快速.独立且高可靠性的 SQL 数据 ...

  9. 玩转SpringBoot:动态排除Starter配置,轻松部署

    引言 在软件开发中,进行本地单元测试是一项常规且必要的任务.然而,在进行单元测试时,有时需要启动一些中间件服务,如Kafka.Elasticjob等.举例来说,我曾经遇到过一个问题:项目中使用了Red ...

  10. string 字符串转为 char *

    std::string str = "abc"; const char *p = str.data(); 更多: https://www.cnblogs.com/devilmayc ...