springmvc的.DispatcherServlet.doDispatch方法解析

来源:互联网 发布:淘宝客服售前流程表 编辑:程序博客网 时间:2024/06/06 02:58

DispatcherServlet的doDispatch方法主要用作职责调度工作,本身主要用于控制流程,主要职责如下:

1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;

2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);

3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);

4、调用HandlerExecutionChain的interceptor和handler

5、解析视图、处理异常,渲染具体的视图等;

参考了博客:http://jinnianshilongnian.iteye.com/blog/1602617

下面是我注释的代码

/** * Process the actual dispatching to the handler. * <p>The handler will be obtained by applying the servlet's HandlerMappings in order. * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters * to find the first that supports the handler class. * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers * themselves to decide which methods are acceptable. * @param request current HTTP request #当前的servelet的HTTP request * @param response current HTTP response #http的response。这两个参数和普通的servelet相同。 * @throws Exception in case of any kind of processing failure */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 {//1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);//2.通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);// Determine handler for the current request.mappedHandler = getHandler(processedRequest);if (mappedHandler == null || mappedHandler.getHandler() == null) {noHandlerFound(processedRequest, response);return;}//3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);// 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();//得到当前的http方法。boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {//处理http的head方法。这种方法应该很少用long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if (logger.isDebugEnabled()) {logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);}if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}//4.1调用HandlerExecutionChain的interceptorif (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}//4.2执行解析handler中的args,调用(invoke) controller的方法。得到视图// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}//4.3调用HandlerExecutionChain的interceptorapplyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {// As of 4.3, we're processing Errors thrown from handler methods as well,// making them available for @ExceptionHandler methods and other scenarios.dispatchException = new NestedServletException("Handler dispatch failed", err);}//5.解析视图、处理异常processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}/** * Return the HandlerExecutionChain for this request. * <p>Tries all handler mappings in order. * @param request current HTTP request * @return the HandlerExecutionChain, or {@code null} if no handler could be found * 2.通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器); */protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {for (HandlerMapping hm : this.handlerMappings) {if (logger.isTraceEnabled()) {logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");}HandlerExecutionChain handler = hm.getHandler(request);if (handler != null) {//只会调用一个handler进行处理return handler;}}return null;}/**3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器); * Return the HandlerAdapter for this handler object. * @param handler the handler object to find an adapter for * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error. */protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {for (HandlerAdapter ha : this.handlerAdapters) {if (logger.isTraceEnabled()) {logger.trace("Testing handler adapter [" + ha + "]");}if (ha.supports(handler)) {return ha;}}throw new ServletException("No adapter for handler [" + handler +"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");}/**5.解析视图、处理异常 * Handle the result of handler selection and handler invocation, which is * either a ModelAndView or an Exception to be resolved to a ModelAndView. */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) {logger.debug("ModelAndViewDefiningException encountered", exception);mv = ((ModelAndViewDefiningException) exception).getModelAndView();}else {Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);//5.1如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。mv = processHandlerException(request, response, handler, exception);errorView = (mv != null);}}//5.2解析视图// Did the handler return a view to render?if (mv != null && !mv.wasCleared()) {render(mv, request, response);if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}else {if (logger.isDebugEnabled()) {logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +"': assuming HandlerAdapter completed request handling");}}if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// Concurrent handling started during a forwardreturn;}if (mappedHandler != null) {mappedHandler.triggerAfterCompletion(request, response, null);}}org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HttpServletRequest, HttpServletResponse)/**执行HandlerExecutionChain的interceptor方法。2.1调用HandlerExecutionChain * Apply preHandle methods of registered interceptors. * @return {@code true} if the execution chain should proceed with the * next interceptor or the handler itself. Else, DispatcherServlet assumes * that this interceptor has already dealt with the response itself. */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];if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);return false;}this.interceptorIndex = i;}}return true;}


原创粉丝点击