首先,先简单的说一下怎么配置SpringMvc的拦截器。
分两步,第一步先定义一个类,实现HandlerInterceptor接口。
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class TestInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle invoke"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle invoke"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion invoke"); } }
第二布,配置springMvc.xml
<!-- 拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*"/> <bean class="com.mmc.interceptor.TestInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
完工。下面分析原理
打开这个DispatcherServlet类,这个类是SpringMvc中最核心的一个类。答案就在doDispatch方法里面:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = checkMultipart(request); multipartRequestParsed = processedRequest != request; // Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { String requestUri = urlPathHelper.getRequestUri(request); logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } try { // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); } finally { if (asyncManager.isConcurrentHandlingStarted()) { return; } } applyDefaultViewName(request, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Error err) { triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); return; } // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } }
里面我标红了四处,第一处对应执行自定义拦截器的preHandler方法,第二处对应执行你的Controller类中的RequestMapping映射的处理方法,第三处是自定义拦截器的postHandle方法,第四处是自定义拦截器的afterCompletion方法。
这些可能很多人都知道,但是我们肯定还有疑问,为什么他能调用到我的拦截器里写的方法呢?
接着往下分析。
于是我们点开我第一处标红那里的mappedHandler.applyPreHandle方法。代码如下:
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { if (getInterceptors() != null) { for (int i = 0; i < getInterceptors().length; i++) { HandlerInterceptor interceptor = getInterceptors()[i]; if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, null); return false; } this.interceptorIndex = i; } } return true; }
看得出来,他是在遍历getInterceptors(),所以在点开这个方法。
public HandlerInterceptor[] getInterceptors() { if (this.interceptors == null && this.interceptorList != null) { this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]); } return this.interceptors; }