springMVC学习笔记五(拦截器详解)

===============================拦截器详解===================================
类似于servlet中的过滤器filter


拦截器常见的应用场景
日志记录
权限检查
性能监控
通用行为
openSessionInView


拦截器接口 
public interface HandlerInterceptor {
  //实现拦截器的预处理
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
   throws Exception;
  //实现处理器的后处理
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
  //请求完毕后的回调方法
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
}




拦载器适配器


public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
 
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
 
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
 
@Override
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}

@Override
public void afterConcurrentHandlingStarted(
HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
}
}






运行流程
HandlerInterceptor1.preHandle
HandlerInterceptor2.preHandle
handlerAdapter
HandlerInterceptor2.postHandle
HandlerInterceptor1.postHandle
view渲染
HandlerInterceptor2.afterCompletion
HandlerInterceptor1.afterCompletion


如果是 HandlerInterceptor2 中断的流程(preHandle 返回 false),此处仅调用它之前拦截器(HandlerInterceptor1HandlerInterceptor1)的 preHandle 返回 true 的 afterCompletion 方法。








每个handlerMapping可以有自已的拦截器
按order值的大小,顺序执行handlerMapping
执行完拦截后,交给目标处理器 


springMVC配置文件的三种配置方法:
方法一:
<!-- 拦截器 -->
<mvc:interceptors>
<bean class="cn.yue.mvc.MyInteceptor" />
</mvc:interceptors>
方法二:
<!-- 拦截匹配的url -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*" />
<bean class="cn.yue.mvc.MyInteceptor" />
</mvc:interceptor>
</mvc:interceptors>


方法三:
<!-- handlerMapping上的拦截器 -->
<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 />
















--------------------------正常流程


自定义拦截器
public class NormalHandlerInterceptor1 extends HandlerInterceptorAdapter {


@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=====NormalHandlerInterceptor1 preHandle=====");
return super.preHandle(request, response, handler);
}


@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("=====NormalHandlerInterceptor1 postHandle=====");
super.postHandle(request, response, handler, modelAndView);
}


@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("=====NormalHandlerInterceptor1 afterCompletion=====");
super.afterCompletion(request, response, handler, ex);
}


}




NormalHandlerInterceptor2同1一样只是打印信息不同


自定义控制器
public class TestHandlerIngerceptorController implements Controller {


@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("=TestHandlerInterceptor=");
return new ModelAndView("test");
}
}






spring配置文件中添加如下内容
<!-- 测试自定义拦截器中方法的执行顺序 -->
<bean name="/test"
class="cn.yue.mvc.controller.TestHandlerIngerceptorController" />
<bean id="handlerInterceptor1" class="cn.yue.mvc.interceptor.NormalHandlerInterceptor1" />
<bean id="handlerInterceptor2" class="cn.yue.mvc.interceptor.NormalHandlerInterceptor2" />


<!-- 指定拦截器链,拦截器的执行顺序就在此指定 -->
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1" />
<ref bean="handlerInterceptor2" />
</list>
</property>
</bean>


测试:http://localhost:8089/test
=====NormalHandlerInterceptor1 preHandle=====
=====NormalHandlerInterceptor2 preHandle=====
=TestHandlerIngerceptorController=
=====NormalHandlerInterceptor2 postHandle=====
=====NormalHandlerInterceptor1 postHandle=====
===============test.jsp
=====NormalHandlerInterceptor2 afterCompletion=====
=====NormalHandlerInterceptor1 afterCompletion=====








------------------------------中断流程
修改NormalHandlerInterceptor2如下内容
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 正常流程
// System.out.println("=====NormalHandlerInterceptor2 preHandle=====");
// return super.preHandle(request, response, handler);
// 中断流程
System.out.println("=====HandlerInterceptor2 preHandle=====");
response.getWriter().print("break");// 流程中断的话需要我们进行响应的处理
return false;// 返回 false 表示流程中断


}


测试控制台输出结果如下:
=====NormalHandlerInterceptor1 preHandle=====
=====HandlerInterceptor2 preHandle=====
=====NormalHandlerInterceptor1 afterCompletion=====




拦截器的应用


性能监控(记录请求的处理时间)




登录检测
为了加强通用性,最好使用servlet规范中的过滤器filter实现 

参考:http://jinnianshilongnian.iteye.com/blog/1752171 
 
posted @ 2014-08-06 14:01  retacn_yue  阅读(251)  评论(0编辑  收藏  举报