Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。

用户可以自己定义一些拦截器来实现特定的功能。

谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺 序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

说到这里,可能大家脑海中有了一个疑问,这不是我们之前学的过滤器吗?是的它和过滤器是有几分相似,但

是也有区别,接下来我们就来说说他们的区别:

  • 过滤器是 servlet 规范中的一部分,任何 java web 工程都可以使用。
  • 拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
  • 过滤器在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截。
  • 拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦 截的。 它也是 AOP 思想的具体应用。 我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口。

直接上代码吧,使用idea创建一个web工程,我们使用maven进行创建,创建过程不演示。

直接看下代码的结构:

首先看我们的

HandlerInterceptorDemo类,这个类实现了拦截器HandlerInterceptor接口

public class HandlerInterceptorDemo implements HandlerInterceptor {
/**
* 在业务处理器处理请求之前被调用
* 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
* 如果返回true
* 执行下一个拦截器,直到所有的拦截器都执行完毕
* 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle(), 在访问Controller之前被调用");
return true; } /**
* 在业务处理器处理请求执行完成后,生成视图之前执行的动作
* 可在modelAndView中加入数据,比如当前时间
*/ public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示");
modelAndView.addObject("date","由拦截器生成的时间:" + new Date());
} /**
* 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
* *
* 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
*/ public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception { System.out.println("afterCompletion(), 在访问视图之后被调用");
}
}

接着是我们的控制器

@Controller
public class controller {
@RequestMapping("/test")
public void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("controller执行了......");
response.getWriter().write("hello......");
}
}

再看下配置文件

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 服务器启动的时候,让DispatcherServlet对象创建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping> </web-app>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 扫描controller的注解,别的不扫描 -->
<context:component-scan base-package="com.helius"/> <mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/> <!--基于ant风格,/**表示拦截一切目录-->
<!-- <mvc:exclude-mapping path=""/>用于指定排除的 url-->
<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
<bean class="com.helius.interceptor.HandlerInterceptorDemo"/>
</mvc:interceptor>
<!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>
<mvc:annotation-driven/>
</beans>

上面的配置文件,我都是采用的最简写法,所以过多的东西都没有考虑,毕竟我们关注的重点不是这个。

运行tomcat,启动容器,

在浏览器上输入

http://localhost:8080/test

浏览器显示:

控制台打印:

preHandle(), 在访问Controller之前被调用
controller执行了......
postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示
afterCompletion(), 在访问视图之后被调用

一切如我们所料。

拦截器的常用使用场景:

1、日志记录 :记录请求信息的日志

2、权限检查,如登录检查

3、性能检测:检测方法的执行时间

注意:配置多个拦截器时,拦截器链的顺序,需要熟稔于心, 可自行百度。

又是一个安静的夜晚,诸事加身,爱人爱己!

最新文章

  1. UnicodeEncodeError: &#39;ascii&#39; codec can&#39;t encode characters in position 820-823: ordinal not in range(128)
  2. MVC 全局异常处理及禁用显示头
  3. 锋利的JQuery(四)
  4. jQuery Jcrop API参数说明(中文版)(转)(图片剪切)
  5. 用R在字符串中提取匹配的部分
  6. A JavaFX based Game Authoring System
  7. U盘安装 OSX
  8. 高性能、高流量Java Web站点打造的22条建议
  9. Linux格式化分区报错Could not start /dev/sda No such file or directory 解决办法
  10. Plupload上传插件简单整理
  11. C#分布式事务解决方案-TransactionScope
  12. 两句话概括cmd和amd的区别
  13. MySQL--如何快速对比数据
  14. python assert的用处
  15. rabbitmq系统学习(三)集群架构
  16. PXC添加新节点
  17. HTML5-表单元素
  18. Weblogic常见故障常:JDBC Connection Pools【转】
  19. spring context 继承
  20. 全新WayOS 配置文件保存工具支持蓝色界面路由版本

热门文章

  1. 【项目管理工具】&mdash;&mdash; Microsoft Office Project 介绍
  2. 9、Hadoop配置文件和HDFS垃圾回收
  3. LG1036
  4. Python爬虫 | Beautifulsoup解析html页面
  5. WinDbg常用命令系列---线程栈中局部上下文切换.frame
  6. 平安银行Java面试-社招-五面(2019/09)
  7. 网站性能测试工具 webbench 的安装和使用-linux
  8. 前后端通信—CORS(支持跨域)
  9. ICEM-四分之一带孔圆板
  10. Web前端开发规范 之html命名规范