SpringMVC拦截器实现分析

一、Servlet Filter与Spring interceptor的执行顺序

成都创新互联公司服务项目包括观山湖网站建设、观山湖网站制作、观山湖网页制作以及观山湖网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,观山湖网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到观山湖省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

Filter有顺序吗?我们怎么控制filter的执行顺序。通过Tomcat的代码分析,servlet在Filter执行完成后才调用,如有多个filter怎么控制执行顺序,首先会想到在web.xml配置某个参数,例如order之类的,但查找一下一番,servlet并没有这个参数。试试filter Mapping的配置的先后顺序,果然有效,原来filter的执行顺序就考filter mapping在web.xml中的顺序。

spring interceptor也是这样的执行顺序,不过interceptor多一个配置参数order通过他也可以来实现interceptor的执行顺序。很多应用场景中,执行顺序还是重要的,比如cache和transaction interceptor的执行顺序,很显然cache应该在transaction之前,这样发现命中了就不用打开事务,如果transaction在前,每次都打开事务即使cache命中,这是一个无谓东动作。

二、利用springMVC的interceptor实现页面性能监控(Filter亦可)

调优***步,找出耗时比较长的页面进行优化。利用interceptor能轻易搞定。interceptor提供了preHandle和postHandle以及afterCompletion三个方法。preHandle调用controller具体方法之前调用,postHandle完成具体方法之后调用,afterCompletion完成对页面的render以后调用,至此整个页面渲染完成。也就是说我们在preHandle记录开始的时间,在afterCompletion记录结束的时间,就可或者整个页面生成的时间。Spring自带StopWatch工具类来实现时间跟踪,关键一点interceptor不是线程安全的。我们需要借助threadlocal来实现线程安全。

 
 
 
  1. @Override 
  2.     public boolean preHandle(HttpServletRequest request, 
  3.             HttpServletResponse response, Object handler) throws Exception { 
  4.         if(usePerformance){ 
  5.             StopWatch stopWatch = new StopWatch(handler.toString()); 
  6.             stopWatchLocal.set(stopWatch); 
  7.             stopWatch.start(handler.toString()); 
  8.         } 
  9.          
  10.         return true; 
  11.     } 
  12.  
  13.  @Override 
  14.     public void afterCompletion(HttpServletRequest request, 
  15.             HttpServletResponse response, Object handler, Exception ex) 
  16.             throws Exception { 
  17.         if(usePerformance){ 
  18.             StopWatch stopWatch = stopWatchLocal.get(); 
  19.             stopWatch.stop(); 
  20.             String currentPath = request.getRequestURI(); 
  21.             String queryString  = request.getQueryString(); 
  22.             queryString = queryString == null ? "":"?" + queryString; 
  23.             log.info("access url path:" + currentPath + queryString +  " |time:" + stopWatch.getTotalTimeMillis()); 
  24.             stopWatchLocal.set(null); 
  25.         } 
  26.     } 

如果你没有使用springMVC可以使用filter来完成:

 
 
 
  1. stopWatch.start(); 
  2. doFilterChain(); 
  3. stopWatch.stop(); 

三、SpringMVC 拦截器实现分析

SpringMVC的拦截器不同于Spring的拦截器,SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet,所以只需要在DispatcherServlet上做文章即可,DispatcherServlet也没有代理,同时SpringMVC管理的Controller也不有代理。哪不难想到我们在执行controller之前做某些动作,执行完毕做某些动作,render完成做某些动作。SpringMVC的拦截器对应提供了三个preHandle,postHandle,afterCompletion方法。只需在三个方法内写我们需要的逻辑就行,多了都是废话,还是代码实在。

 
 
 
  1. HandlerInterceptor[] interceptors = mappedHandler.getInterceptors(); 
  2.                 if (interceptors != null) { 
  3.                     for (int i = 0; i < interceptors.length; i++) { 
  4.                         HandlerInterceptor interceptor = interceptors[i]; 
  5. //ha.handle是调用具体的controller在此之前执行preHandle                      if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { 
  6.                             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); 
  7.                             return; 
  8.                         } 
  9.                         interceptorIndex = i; 
  10.                     } 
  11.                 } 
  12.  
  13.                 // Actually invoke the handler. 
  14.                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 

完成调用之后,调用render(),***执行afterCompletion()。

 
 
 
  1. if (interceptors != null) { 
  2.                 for (int i = interceptors.length - 1; i >= 0; i--) { 
  3.                     HandlerInterceptor interceptor = interceptors[i]; 
  4.                     interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv); 
  5.                 } 
  6.             } 
  7.         } 
  8.         catch (ModelAndViewDefiningException ex) { 
  9.             logger.debug("ModelAndViewDefiningException encountered", ex); 
  10.             mv = ex.getModelAndView(); 
  11.         } 
  12.         catch (Exception ex) { 
  13.             Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); 
  14.             mv = processHandlerException(processedRequest, response, handler, ex); 
  15.             errorView = (mv != null); 
  16.         } 
  17.  
  18.         // Did the handler return a view to render? 
  19.         if (mv != null && !mv.wasCleared()) { 
  20.             render(mv, processedRequest, response); 
  21.             if (errorView) { 
  22.                 WebUtils.clearErrorRequestAttributes(request); 
  23.             } 
  24.         } 
  25.         else { 
  26.             if (logger.isDebugEnabled()) { 
  27.                 logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + 
  28.                         "': assuming HandlerAdapter completed request handling"); 
  29.             } 
  30.         } 
  31.  
  32.         // Trigger after-completion for successful outcome. 
  33.         triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); 

原文链接:http://exceptioneye.iteye.com/blog/1267248

网站栏目:SpringMVC拦截器实现分析
转载来于:http://www.mswzjz.com/qtweb/news32/187082.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联