Spring为我们提供了:org.springframework.web.servlet.HandlerInterceptor接口,

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

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

有以下三个方法:

Action之前执行

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

生成视图之前执行

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

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

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

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

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

在postHandle中,有机会修改ModelAndView;

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

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

如何使用拦截器

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

public class MyInterceptor implements HandlerInterceptor {...}

在springMVC的配置文件中配置有三种方法

一、拦截所有URL

<mvc:interceptors>
<bean class="com.itmyhome.MyInterceptor" />
</mvc:interceptors>

二、拦截匹配的URL

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/login" />
<bean class="com.itmyhome.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

三、HandlerMappint上的拦截器

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

如果使用了<mvc:annotation-driven />, 它会自动注册DefaultAnnotationHandlerMapping 与

AnnotationMethodHandlerAdapter 这两个bean,所以就没有机会再给它注入interceptors属性,就无法指定拦截器。

当然我们可以通过人工配置上面的两个Bean,不使用 <mvc:annotation-driven />,

就可以给interceptors属性注入拦截器了。

拦截器MyInterceptor类

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 { public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception e)
throws Exception {
System.out.println("******afterCompletion******"); } public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView arg3)
throws Exception {
System.out.println("******postHandle******"); } /**
* 如果返回false 从当前拦截器往回执行所有拦截器的afterCompletion方法,再退回拦截器链 如果返回true
* 执行下一个拦截器,直到所有拦截器都执行完毕 再运行被拦截的Controller
* 然后进入拦截器链从最后一个拦截器往回运行所有拦截器的postHandle方法
* 接着依旧是从最后一个拦截器往回执行所有拦截器的afterCompletion方法
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("******preHandle******");
return true;
}
}

spring配置文件

<!-- 拦截所以URL
<mvc:interceptors>
<bean class="com.itmyhome.MyInterceptor" />
</mvc:interceptors>
-->
<!-- 拦截匹配URL -->
<mvc:interceptors >
<mvc:interceptor>
<mvc:mapping path="/login" />
<bean class="com.itmyhome.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors> <!-- HandlerMappint上的拦截器
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<bean class="com.itmyhome.MyInterceptor"></bean>
</list>
</property>
</bean>--> <!-- 默认扫描的包路径-->
<context:component-scan base-package="com.itmyhome" />
<!-- 添加注解驱动 -->
<mvc:annotation-driven /> <!-- 如果使用HandlerMappint拦截器则注释以上注册驱动的方法,使用以下人工配置bean -->
<!-- <bean class="com.itmyhome.Login"></bean>--> <!-- 处理器 -->
<bean name="/login" class="com.itmyhome.Login"></bean> <!-- HandlerMapping
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>-->
<!-- HandlerAdapter
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>--> <!-- 定义跳转的文件的前后缀 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" /> <!-- 默认放在WebRoot下 -->
<property name="suffix" value=".jsp" />
</bean>

测试URL:http://localhost:8080/spring_Interceptor/login

查看后台会执行拦截器代码

项目源码下载:http://download.csdn.net/detail/itmyhome/7372023

最新文章

  1. CSS中一些常见的兼容性问题
  2. alpha-beta剪枝搜索
  3. Protocol 编码的三种常用方式
  4. Codeforces Round #359(div 2)
  5. NSString和NSMutableString的创建及其一些常用方法
  6. WCF的传输安全(读书笔记)
  7. POJ 3666 Making the Grade (DP滚动数组)
  8. 从客户端(FCKeditor1=&quot;&lt;p&gt;...&quot;)中检测到有潜在危险的 Request.Form 值。
  9. Web Builder
  10. spring框架应用系列三:切面编程(带参数)
  11. Windows rundll32的用法-批处理管理打印机
  12. markdown改变字体颜色和大小
  13. maven:打包时报错,报&rsquo;找不到符号&rsquo;
  14. 收银台数据库存储AES加解密
  15. ASP.NET Web API实现微信公众平台开发(三)自定义菜单
  16. Hive和SparkSQL:基于 Hadoop 的数据仓库工具
  17. 加减plugin
  18. union与union all的用法给区别
  19. bzoj千题计划268:bzoj3131: [Sdoi2013]淘金
  20. hiho# 1465 重复旋律8 循环串计数 后缀自动机

热门文章

  1. Javascript闭包的一些研究
  2. Android MediaPlayer 和 NativePlayer 播放格式控制
  3. leetcode先刷_Merge Two Sorted Lists
  4. Xutils呼叫流源代码文件下载方法
  5. windows系统下c语言暂停程序
  6. HDU 1484 Basic wall maze (dfs + 记忆)
  7. CKPlayer从Cookie里读取上次播放记录的一个demo
  8. c#万能视频播放器(附代码)
  9. [译]JDK 6 and JDK 7中的subString()方法
  10. leetcode第33题--Search for a Range