Interceptor拦截器用于拦截Controller层接口,表现形式有点像Spring的AOP,但是AOP是针对单一的方法。Interceptor是针对Controller接口以及可以处理request和response对象。

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
HandlerExecutionChaingetHandler(HttpServletRequest request) throws Exception {
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler,
request);return executionChain; } protected HandlerExecutionChain
getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handlerinstanceof 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 pathMatcher) { 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); } } } } }

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信