拦截器接口
1 2 3 4 5 6 7
| public interface HandlerInterceptor { boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;
void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception; }
|
preHandle: 预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器。返回TRUE
,继续执行;返回FALSE
,中断流程。
postHandle: 实现处理器的后处理,但在渲染视图之前。
afterCompletion: 整个请求处理完毕回调方法,即在视图渲染完毕时回调
拦截器适配器(缺省适配器实现)
在实现自定义的拦截器时,无需实现HandlerInterceptor,只需继承HandlerInterceptorAdapter,并实现所需功能即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public interface AsyncHandlerInterceptor extends HandlerInterceptor { void afterConcurrentHandlingStarted(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception; }
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { public HandlerInterceptorAdapter() { }
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; }
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { }
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { } }
|
拦截器执行流程
拦截器的执行流程,可以通过DispatcherServlet的源码进行分析。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try { try { ModelAndView err = null; Object dispatchException = null;
try { processedRequest = this.checkMultipart(request); multipartRequestParsed = processedRequest != request; mappedHandler = this.getHandler(processedRequest); if(mappedHandler == null || mappedHandler.getHandler() == null) { this.noHandlerFound(processedRequest, response); return; }
HandlerAdapter err1 = this.getHandlerAdapter(mappedHandler.getHandler()); String method = request.getMethod(); boolean isGet = "GET".equals(method); if(isGet || "HEAD".equals(method)) { long lastModified = err1.getLastModified(request, mappedHandler.getHandler()); if(this.logger.isDebugEnabled()) { this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); }
if((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) { return; } }
if(!mappedHandler.applyPreHandle(processedRequest, response)) { return; }
err = err1.handle(processedRequest, response, mappedHandler.getHandler()); if(asyncManager.isConcurrentHandlingStarted()) { return; }
this.applyDefaultViewName(processedRequest, err); mappedHandler.applyPostHandle(processedRequest, response, err); } catch (Exception var20) { dispatchException = var20; } catch (Throwable var21) { dispatchException = new NestedServletException("Handler dispatch failed", var21); }
this.processDispatchResult(processedRequest, response, mappedHandler, err, (Exception)dispatchException); } catch (Exception var22) { this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22); } catch (Throwable var23) { this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23)); }
} finally { if(asyncManager.isConcurrentHandlingStarted()) { if(mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else if(multipartRequestParsed) { this.cleanupMultipart(processedRequest); }
} }
|
代码1.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { HandlerInterceptor[] interceptors = this.getInterceptors(); if(!ObjectUtils.isEmpty(interceptors)) { for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) { HandlerInterceptor interceptor = interceptors[i]; if(!interceptor.preHandle(request, response, this.handler)) { this.triggerAfterCompletion(request, response, (Exception)null); return false; } } }
return true; }
|
代码1.2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { HandlerInterceptor[] interceptors = this.getInterceptors(); if(!ObjectUtils.isEmpty(interceptors)) { for(int i = this.interceptorIndex; i >= 0; --i) { HandlerInterceptor interceptor = interceptors[i];
try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable var8) { logger.error("HandlerInterceptor.afterCompletion threw exception", var8); } } }
}
|
代码1.3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception { boolean errorView = false; if(exception != null) { if(exception instanceof ModelAndViewDefiningException) { this.logger.debug("ModelAndViewDefiningException encountered", exception); mv = ((ModelAndViewDefiningException)exception).getModelAndView(); } else { Object handler = mappedHandler != null?mappedHandler.getHandler():null; mv = this.processHandlerException(request, response, handler, exception); errorView = mv != null; } }
if(mv != null && !mv.wasCleared()) { this.render(mv, request, response); if(errorView) { WebUtils.clearErrorRequestAttributes(request); } } else if(this.logger.isDebugEnabled()) { this.logger.debug("Null ModelAndView returned to DispatcherServlet with name \'" + this.getServletName() + "\': assuming HandlerAdapter completed request handling"); }
if(!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { if(mappedHandler != null) { mappedHandler.triggerAfterCompletion(request, response, (Exception)null); }
} }
|
总结:
intercepor.preHandle -> 获取HandleAdapter -> intercepor.postHandle -> View 渲染 -> intercepor.afterCompletion
intercepor.preHandle -> 部分intercepor.afterCompletion
应用
性能监控实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class StopWatchHandlerInterceptor extends HandlerInterceptorAdapter { private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("StopWatch-StartTime");
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { long beginTime = System.currentTimeMillis(); startTimeThreadLocal.set(beginTime); return true; }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { long endTime = System.currentTimeMillis(); System.out.println("方法执行时间为:" + (endTime - startTimeThreadLocal.get())); } }
|