HandlerInterceptor 拦截器
(1)preHandle: 在执行controller处理之前执行,返回值为boolean ,返回值为true时接着执行postHandle和afterCompletion,如果我们返回false则中断执行
(2)postHandle:在执行controller的处理后,在ModelAndView处理前执行
(3)afterCompletion :在DispatchServlet执行完ModelAndView之后执行
Source Code
1 public interface HandlerInterceptor { 2 3 /** 4 * Intercept the execution of a handler. Called after HandlerMapping determined 5 * an appropriate handler object, but before HandlerAdapter invokes the handler. 6 * <p>DispatcherServlet processes a handler in an execution chain, consisting 7 * of any number of interceptors, with the handler itself at the end. 8 * With this method, each interceptor can decide to abort the execution chain, 9 * typically sending an HTTP error or writing a custom response. 10 * <p><strong>Note:</strong> special considerations apply for asynchronous 11 * request processing. For more details see 12 * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}. 13 * <p>The default implementation returns {@code true}. 14 * @param request current HTTP request 15 * @param response current HTTP response 16 * @param handler chosen handler to execute, for type and/or instance evaluation 17 * @return {@code true} if the execution chain should proceed with the 18 * next interceptor or the handler itself. Else, DispatcherServlet assumes 19 * that this interceptor has already dealt with the response itself. 20 * @throws Exception in case of errors 21 */ 22 default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 23 throws Exception { 24 25 return true; 26 } 27 28 /** 29 * Intercept the execution of a handler. Called after HandlerAdapter actually 30 * invoked the handler, but before the DispatcherServlet renders the view. 31 * Can expose additional model objects to the view via the given ModelAndView. 32 * <p>DispatcherServlet processes a handler in an execution chain, consisting 33 * of any number of interceptors, with the handler itself at the end. 34 * With this method, each interceptor can post-process an execution, 35 * getting applied in inverse order of the execution chain. 36 * <p><strong>Note:</strong> special considerations apply for asynchronous 37 * request processing. For more details see 38 * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}. 39 * <p>The default implementation is empty. 40 * @param request current HTTP request 41 * @param response current HTTP response 42 * @param handler handler (or {@link HandlerMethod}) that started asynchronous 43 * execution, for type and/or instance examination 44 * @param modelAndView the {@code ModelAndView} that the handler returned 45 * (can also be {@code null}) 46 * @throws Exception in case of errors 47 */ 48 default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 49 @Nullable ModelAndView modelAndView) throws Exception { 50 } 51 52 /** 53 * Callback after completion of request processing, that is, after rendering 54 * the view. Will be called on any outcome of handler execution, thus allows 55 * for proper resource cleanup. 56 * <p>Note: Will only be called if this interceptor's {@code preHandle} 57 * method has successfully completed and returned {@code true}! 58 * <p>As with the {@code postHandle} method, the method will be invoked on each 59 * interceptor in the chain in reverse order, so the first interceptor will be 60 * the last to be invoked. 61 * <p><strong>Note:</strong> special considerations apply for asynchronous 62 * request processing. For more details see 63 * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}. 64 * <p>The default implementation is empty. 65 * @param request current HTTP request 66 * @param response current HTTP response 67 * @param handler handler (or {@link HandlerMethod}) that started asynchronous 68 * execution, for type and/or instance examination 69 * @param ex any exception thrown on handler execution, if any; this does not 70 * include exceptions that have been handled through an exception resolver 71 * @throws Exception in case of errors 72 */ 73 default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, 74 @Nullable Exception ex) throws Exception { 75 } 76 77 }
拦截器的功能
从接口中的3个方法,可以看出,类似于AOP的操作,可以完成在请求到达方法之前,完成方法之后,以及视图解析之前被调用,例如在调用方法前做用户权限的验证,日志的记录等等。HandlerInterceptorAdapter 类实现了HandlerInterceptor接口,自定义的拦截器也可以通过继承该类来实现拦截。
拦截器流程图
拦截器的执行过程是有序的,多个interceptor可以在 xml中 进行配置。
<mvc:interceptors> <bean class="com.interceptor.TestInterceptor" /> <bean class="com.interceptor.DataInterceptor" /> </mvc:interceptors>
[2020-05-20 11:12:30,645] Artifact springmvcdemo:war exploded: Artifact is deployed successfully
[2020-05-20 11:12:30,645] Artifact springmvcdemo:war exploded: Deploy took 2,023 milliseconds
TestInterceptor preHandle....
DataInterceptor preHandle....
DataInterceptor postHandle....
TestInterceptor postHandle....
DataInterceptor afterCompletion....
TestInterceptor afterCompletion....
Single Interceptor
Multi Interceptor
interceptor1配置在interceptor2 之前
Source Code 2
1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 ……… 3 try { 4 ……… 5 try { 6 ……… 7 mappedHandler = getHandler(processedRequest); 8 9 if (!mappedHandler.applyPreHandle(processedRequest, response)) { 10 return; 11 } 12 13 // Actually invoke the handler. 14 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 15 ……… 16 mappedHandler.applyPostHandle(processedRequest, response, mv); 17 } 18 catch (Exception ex) { 19 ……… 20 } 21 catch (Throwable err) { 22 ……… 23 } 24 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); 25 } 26 catch (Exception ex) { 27 triggerAfterCompletion(processedRequest, response, mappedHandler, ex); 28 } 29 catch (Throwable err) { 30 triggerAfterCompletion(processedRequest, response, mappedHandler, 31 new NestedServletException("Handler processing failed", err)); 32 } 33 34 }
篇幅有限以上只是拦截器的基本玩法,细节点并未涉及,有时间再写里面的 HandlerExecutionChain