springmvc拦截器详解
来源:互联网 发布:俄罗斯经济 知乎 编辑:程序博客网 时间:2024/06/05 00:26
一,拦截器简介
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; }
preHandle: 预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现);
返回值:true表示继续流程(如调用下一个拦截器或处理器);
false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
postHandle: 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中
二,运行流程图
正常流程
中断流程中,比如是HandlerInterceptor4中断的流程(preHandle返回false),此处仅调用它之前拦截器(HandlerInterceptor3)的preHandle返回true的afterCompletion方法。
问题:
我们的拦截器是单例,因此不管用户请求多少次都只有一个拦截器实现,即线程不安全,那我们应该怎么记录时间呢?
解决方案是使用ThreadLocal,它是线程绑定的变量,提供线程局部变量(一个线程一个ThreadLocal,A线程的ThreadLocal只能看到A线程的ThreadLocal,不能看到B线程的ThreadLocal)
import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.core.NamedThreadLocal;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class StopWatchHandlerInterceptor extends HandlerInterceptorAdapter { private NamedThreadLocal<Long> startTimeThreadLocal=new NamedThreadLocal<Long>("StopWatch-stratTime");@Override public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {// TODO Auto-generated method stub long beginTime =System.currentTimeMillis(); startTimeThreadLocal.set(beginTime); return true; }@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {// TODO Auto-generated method stub long endTime=System.currentTimeMillis(); long beginTime=startTimeThreadLocal.get(); long consumeTime =endTime - beginTime;System.out.println("123"+String.format("%s consume %d millis", request.getRequestURI(),consumeTime));}}
***-service.xml的配置
<!-- 拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/test"/> <bean class="com.cn.main.StopWatchHandlerInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>url为test时,启动对应路径下的拦截器
- SpringMVC拦截器详解
- SpringMVC拦截器详解
- SpringMVC 拦截器 详解
- springmvc拦截器详解
- SpringMVC拦截器详解
- SpringMVC拦截器详解
- SpringMVC自定义拦截器详解
- springMVC之拦截器详解
- SpringMVC自定义拦截器详解
- SpringMVC自定义拦截器详解
- springMVC教程--拦截器详解
- SpringMVC拦截器配置详解
- 第五章---SpringMVC----拦截器详解
- SpringMVC拦截器详解[附带源码分析]
- SpringMVC拦截器详解[附带源码分析]
- SpringMVC中使用Interceptor拦截器详解
- 自定义SpringMVC自定义拦截器详解
- SpringMVC之拦截器使用详解
- Maven : 将Jar安装到本地仓库和Jar上传到私服
- Effective c++之Item 25: 考虑支持不抛异常的 swap
- 【Android】底部标签页,Tabhost置底
- springboot文件配置
- Activity的生命周期可能造成的问题
- springmvc拦截器详解
- 简单Demo:动态调用自己编写的动态链接库
- 管理OCR与Voting Disk(原创)
- Java:按值传递还是按引用传递详细解说
- php 获取文件mime类型的方法
- java内存管理机制
- Python起步之数据类型
- Android的网络请求方式解析
- 小结Mysql常用快捷键