springMVC之Interceptor拦截器
2018-01-24 17:34
696 查看
Interceptor拦截器用于拦截Controller层接口,表现形式有点像Spring的AOP,但是AOP是针对单一的方法。Interceptor是针对Controller接口以及可以处理request和response对象。
preHandle是调用Controller之前被调用,当返回false后,会跳过之后的拦截器,并且不会执行所有拦截器的postHandle,并调用返回true的拦截器的afterCompletion方法。
postHandle是调用Controller之后被调用,但是在渲染View页面之前。
afterCompletion是调用完Controller接口,渲染View页面最后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法,顺序相反。
和HandlerInterceptor很相似的要有一个AsyncHandlerInterceptor接口,只是多了个afterConcurrentHandlingStarted个方法,当接口使用了异步的方法的时候调用。
上述的拦截器的信息,都来自与下面的配置文件
1 HandlerInterceptor接口的定义
我们先来看下HandlerInterceptor接口的定义,定义了三个接口,分别是preHandle、postHandle、afterCompletion。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之前被调用,当返回false后,会跳过之后的拦截器,并且不会执行所有拦截器的postHandle,并调用返回true的拦截器的afterCompletion方法。
postHandle是调用Controller之后被调用,但是在渲染View页面之前。
afterCompletion是调用完Controller接口,渲染View页面最后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法,顺序相反。
和HandlerInterceptor很相似的要有一个AsyncHandlerInterceptor接口,只是多了个afterConcurrentHandlingStarted个方法,当接口使用了异步的方法的时候调用。
public interface AsyncHandlerInterceptor extends HandlerInterceptor { void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; }
2 HandlerInterceptor接口的定义
2.1 DispatcherServlet里doDispatch主处理逻辑
DispatcherServlet里doDispatch()就是springMVC的处理主要逻辑。因此肯定包含了拦截器的主要处理逻辑protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { try { try { //.......省略代码 //返回HandlerExecutionChain 其中包含了拦截器队列 mappedHandler = getHandler(processedRequest); //调用拦截器PreHandle方法,若返回false不执行Controller逻辑,并不调用下面的PostHandle方法 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 处理Controller层 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); applyDefaultViewName(processedRequest, mv); //调用拦截器的PostHandle方法 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { //抛出异常后都会调用拦截器AfterCompletion方法 triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { //若Controller方法为异步调用,则执行拦截器afterConcurrentHandlingStarted(只有AsyncHandlerInterceptor拦截器才有) mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } } }
2.2 获取拦截器
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { //返回HandlerExecutionChain 其中包含了拦截器队列 mappedHandler = getHandler(processedRequest); } //返回HandlerExecutionChain public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); return executionChain; } protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); //根据url和拦截器异常的配置url做对比,若符合则加入队列 String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); for (HandlerInterceptor interceptor : this.adaptedInterceptors) { if (interceptor instanceof MappedInterceptor) { MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } else { chain.addInterceptor(interceptor); } } return chain; } public boolean matches(String lookupPath, PathMatcher pathMa 4000 tcher) { PathMatcher pathMatcherToUse = (this.pathMatcher != null) ? this.pathMatcher : pathMatcher; if (this.excludePatterns != null) { for (String pattern : this.excludePatterns) { if (pathMatcherToUse.match(pattern, lookupPath)) { return false; } } } if (this.includePatterns == null) { return true; } else { for (String pattern : this.includePatterns) { if (pathMatcherToUse.match(pattern, lookupPath)) { return true; } } return false; } }
上述的拦截器的信息,都来自与下面的配置文件
<!-- 拦截器链 --> <mvc:interceptors> <mvc:interceptor> <!--拦截器mapping 符合的才会执行拦截器--> <mvc:mapping path="/**"/> <!--在拦截器mapping中除去下面的url --> <mvc:exclude-mapping path="/transactional_test/*"/> <!--执行的拦截器--> <ref bean="apiInterceptor"/> </mvc:interceptor> </mvc:interceptors> <bean id="apiInterceptor" class="com.lk.dome.interceptor.ApiInterceptor"/>
2.3 处理拦截器
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; //若返回false,则直接执行拦截器的triggerAfterCompletion方法 if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, null); //直接返回,在外层的doDispatch逻辑中不执行后面的逻辑 return false; } //记录成功执行的拦截器个数 this.interceptorIndex = i; } } return true; } void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { //拦截器队列从后往前之心,顺序相反 for (int i = interceptors.length - 1; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; interceptor.postHandle(request, response, this.handler, mv); } } } void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { //interceptorIndex为执行成功的拦截器标志 for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } } //异步方法调用,拦截器必须属于AsyncHandlerInterceptor接口 void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = interceptors.length - 1; i >= 0; i--) { if (interceptors[i] instanceof AsyncHandlerInterceptor) { try { AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i]; asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler); } catch (Throwable ex) { logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted", ex); } } } } }
相关文章推荐
- Java过滤器(Filter)与SpringMVC拦截器(Interceptor)之间的关系与区别
- springmvc拦截器HandlerInterceptorAdapter预处理
- SpringMVC的拦截器(Interceptor)和过滤器(Filter)的区别与联系
- springMVC拦截器 interceptor!
- Springmvc第三讲学习笔记,拦截器Interceptor的使用
- java 过滤器(Filter)与springMVC 拦截器(interceptor)的实现案例
- SpringMVC拦截器Interceptor
- SpringMVC的拦截器(Interceptor)和过滤器(Filter)的区别与联系
- SpringMVC 中的Interceptor 拦截器
- SpringMVC之Interceptor拦截器之登录拦截器
- springMVC中多个拦截器Interceptor的执行顺序
- Spring MVC 中 HandlerInterceptorAdapter的使用[SpringMVC中请求拦截器的实现]
- SpringMVC 拦截器Interceptor
- springMVC中多个拦截器Interceptor的执行顺序
- SpringMVC 中的Interceptor 拦截器(HandlerInteceptor)
- springmvc 拦截器interceptor
- 关于springMVC中的使用拦截器interceptor问题
- SpringMVC -- 梗概--源码--贰--拦截器:Interceptor
- springMvc自定义拦截器HandlerInterceptorAdapter的认识
- springmvc之interceptor(拦截器)