springMVC之Interceptor拦截器
轉自:https://blog.csdn.net/qq_25673113/article/details/79153547
Interceptor攔截器用于攔截Controller層接口,表現形式有點像Spring的AOP,但是AOP是針對單一的方法。Interceptor是針對Controller接口以及可以處理request和response對象。
1 HandlerInterceptor接口的定義
我們先來看下HandlerInterceptor接口的定義,定義了三個接口,分別是preHandle、postHandle、afterCompletion。
preHandle是調用Controller之前被調用,當返回false后,會跳過之后的攔截器,并且不會執行所有攔截器的postHandle,并調用返回true的攔截器的afterCompletion方法。
postHandle是調用Controller之后被調用,但是在渲染View頁面之前。
afterCompletion是調用完Controller接口,渲染View頁面最后調用。返回true的攔截器都會調用該攔截器的afterCompletion方法,順序相反。
和HandlerInterceptor很相似的要有一個AsyncHandlerInterceptor接口,只是多了個afterConcurrentHandlingStarted個方法,當接口使用了異步的方法的時候調用。
1 public interface AsyncHandlerInterceptor extends HandlerInterceptor { 2 3 void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) 4 throws Exception; 5 6 }2 HandlerInterceptor接口的定義
2.1?DispatcherServlet里doDispatch主處理邏輯
DispatcherServlet里doDispatch()就是springMVC的處理主要邏輯。因此肯定包含了攔截器的主要處理邏輯
1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 try { 3 4 try { 5 //.......省略代碼 6 7 //返回HandlerExecutionChain 其中包含了攔截器隊列 8 mappedHandler = getHandler(processedRequest); 9 10 //調用攔截器PreHandle方法,若返回false不執行Controller邏輯,并不調用下面的PostHandle方法 11 if (!mappedHandler.applyPreHandle(processedRequest, response)) { 12 return; 13 } 14 15 // 處理Controller層 16 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 17 18 applyDefaultViewName(processedRequest, mv); 19 20 //調用攔截器的PostHandle方法 21 mappedHandler.applyPostHandle(processedRequest, response, mv); 22 } 23 catch (Exception ex) { 24 dispatchException = ex; 25 } 26 27 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); 28 } 29 catch (Exception ex) { 30 //拋出異常后都會調用攔截器AfterCompletion方法 31 triggerAfterCompletion(processedRequest, response, mappedHandler, ex); 32 } 33 finally { 34 if (asyncManager.isConcurrentHandlingStarted()) { 35 // Instead of postHandle and afterCompletion 36 if (mappedHandler != null) { 37 //若Controller方法為異步調用,則執行攔截器afterConcurrentHandlingStarted(只有AsyncHandlerInterceptor攔截器才有) 38 mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); 39 } 40 } 41 } 42 }2.2 獲取攔截器
1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 //返回HandlerExecutionChain 其中包含了攔截器隊列 3 mappedHandler = getHandler(processedRequest); 4 } 5 //返回HandlerExecutionChain 6 public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { 7 8 HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); 9 return executionChain; 10 } 11 12 protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { 13 HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? 14 (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); 15 16 //根據url和攔截器異常的配置url做對比,若符合則加入隊列 17 String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); 18 for (HandlerInterceptor interceptor : this.adaptedInterceptors) { 19 if (interceptor instanceof MappedInterceptor) { 20 MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; 21 if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { 22 chain.addInterceptor(mappedInterceptor.getInterceptor()); 23 } 24 } 25 else { 26 chain.addInterceptor(interceptor); 27 } 28 } 29 return chain; 30 } 31 32 public boolean matches(String lookupPath, PathMatcher pathMatcher) { 33 PathMatcher pathMatcherToUse = (this.pathMatcher != null) ? this.pathMatcher : pathMatcher; 34 if (this.excludePatterns != null) { 35 for (String pattern : this.excludePatterns) { 36 if (pathMatcherToUse.match(pattern, lookupPath)) { 37 return false; 38 } 39 } 40 } 41 if (this.includePatterns == null) { 42 return true; 43 } 44 else { 45 for (String pattern : this.includePatterns) { 46 if (pathMatcherToUse.match(pattern, lookupPath)) { 47 return true; 48 } 49 } 50 return false; 51 } 52 }上述的攔截器的信息,都來自與下面的配置文件
1 <!-- 攔截器鏈 --> 2 <mvc:interceptors> 3 4 <mvc:interceptor> 5 <!--攔截器mapping 符合的才會執行攔截器--> 6 <mvc:mapping path="/**"/> 7 <!--在攔截器mapping中除去下面的url --> 8 <mvc:exclude-mapping path="/transactional_test/*"/> 9 <!--執行的攔截器--> 10 <ref bean="apiInterceptor"/> 11 </mvc:interceptor> 12 </mvc:interceptors> 13 14 <bean id="apiInterceptor" class="com.lk.dome.interceptor.ApiInterceptor"/> 15 ---------------------2.3 處理攔截器
1 boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 HandlerInterceptor[] interceptors = getInterceptors(); 3 if (!ObjectUtils.isEmpty(interceptors)) { 4 for (int i = 0; i < interceptors.length; i++) { 5 HandlerInterceptor interceptor = interceptors[i]; 6 //若返回false,則直接執行攔截器的triggerAfterCompletion方法 7 if (!interceptor.preHandle(request, response, this.handler)) { 8 triggerAfterCompletion(request, response, null); 9 //直接返回,在外層的doDispatch邏輯中不執行后面的邏輯 10 return false; 11 } 12 //記錄成功執行的攔截器個數 13 this.interceptorIndex = i; 14 } 15 } 16 return true; 17 } 18 void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { 19 HandlerInterceptor[] interceptors = getInterceptors(); 20 if (!ObjectUtils.isEmpty(interceptors)) { 21 //攔截器隊列從后往前之心,順序相反 22 for (int i = interceptors.length - 1; i >= 0; i--) { 23 HandlerInterceptor interceptor = interceptors[i]; 24 interceptor.postHandle(request, response, this.handler, mv); 25 } 26 } 27 } 28 void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) 29 throws Exception { 30 31 HandlerInterceptor[] interceptors = getInterceptors(); 32 if (!ObjectUtils.isEmpty(interceptors)) { 33 //interceptorIndex為執行成功的攔截器標志 34 for (int i = this.interceptorIndex; i >= 0; i--) { 35 HandlerInterceptor interceptor = interceptors[i]; 36 try { 37 interceptor.afterCompletion(request, response, this.handler, ex); 38 } 39 catch (Throwable ex2) { 40 logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); 41 } 42 } 43 } 44 } 45 //異步方法調用,攔截器必須屬于AsyncHandlerInterceptor接口 46 void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) { 47 HandlerInterceptor[] interceptors = getInterceptors(); 48 if (!ObjectUtils.isEmpty(interceptors)) { 49 for (int i = interceptors.length - 1; i >= 0; i--) { 50 if (interceptors[i] instanceof AsyncHandlerInterceptor) { 51 try { 52 AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i]; 53 asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler); 54 } 55 catch (Throwable ex) { 56 logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted", ex); 57 } 58 } 59 } 60 } 61 }?
?
轉載于:https://www.cnblogs.com/sharpest/p/10416198.html
總結
以上是生活随笔為你收集整理的springMVC之Interceptor拦截器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈MySQL架构体系
- 下一篇: 使用component小程序