springMvc请求到返回的流程request-->response

springMvc核心类 : org.springframework.web.servlet.DispatcherServlet

核心方法:org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)

	/**
	 * 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
	 * @param response current HTTP response
	 * @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;
		int interceptorIndex = -1;

		try {
			ModelAndView mv;
			boolean errorView = false;

			try {
				//将请求转换为多部分请求,并使多部分解析器可用
				processedRequest = checkMultipart(request);


				//将请求的requestUri 和容器所有的mapping比较是否存在
				mappedHandler = getHandler(processedRequest, false);
				if (mappedHandler == null || mappedHandler.getHandler() == null) {
					noHandlerFound(processedRequest, response);
					//"No mapping found for HTTP request with URI [" + requestUri +"] in DispatcherServlet with name '" + getServletName() + "'"
					//返回找不到对应requestUri
					return;
				}


				// Determine handler adapter for the current request.
				//返回传入控制器的代理
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());


                // Process last-modified header, if supported by the handler.
				/**在http协议中,浏览器对访问过的页面缓存后,它将会在以后访问该页面时,
					将会根据LastModified头字段指定的时间值生成If-Modified-Since头字段,
					作为缓存页面的最新更新时间。如果网页的最后修改时间比If-Modified-Since头字段指定的时间早的话,
					web服务器就会请求的页面,如果自If-modified-Since指定的时间以来,网页内容没有被修改的话,
					服务器就会返回一个304响应头,一次告诉浏览器继续使用已缓存的页面。*/
				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;
					}
				}


				// Apply preHandle methods of registered interceptors.
				//应用已注册的拦截器的预处理方法。
				/**拦截处理程序的执行。在HandlerMapping后决定,适当的处理程序对象,但在HandlerAdapter调用处理程序之前。
				 < p > DispatcherServlet处理执行链中的处理程序,包括任意数量的拦截器,最后是处理程序本身。
					使用此方法,每个拦截器可以决定中止执行链*/
				HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
				if (interceptors != null) {
					for (int i = 0; i < interceptors.length; i++) {
						HandlerInterceptor interceptor = interceptors[i];
						if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
							triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
							return;
						}
						interceptorIndex = i;
					}
				}

				// Actually invoke the handler.
				//实际调用处理程序
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				// Do we need view name translation?
				if (mv != null && !mv.hasView()) {
					mv.setViewName(getDefaultViewName(request));
				}

				// Apply postHandle methods of registered interceptors.
				//对已注册的拦截器的方法进行应用。
				if (interceptors != null) {
					for (int i = interceptors.length - 1; i >= 0; i--) {
						HandlerInterceptor interceptor = interceptors[i];
						interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
					}
				}
			}
			catch (ModelAndViewDefiningException ex) {
				logger.debug("ModelAndViewDefiningException encountered", ex);
				mv = ex.getModelAndView();
			}
			catch (Exception ex) {
				Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
				mv = processHandlerException(processedRequest, response, handler, ex);
				errorView = (mv != null);
			}
			//使用了@ResponseBody注解,该注解直接将控制器中的返回值绑定到web响应体里,如果返回的是字符串,那么该字符串就显示在浏览器上
			// Did the handler return a view to render?  是否返回视图
			if (mv != null && !mv.wasCleared()) {
				render(mv, processedRequest, 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");
				}
			}

			// Trigger after-completion for successful outcome.
			//成功的结果触发后续工作 interceptorComplete
			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
		}

		catch (Exception ex) {
			// Trigger after-completion for thrown exception.
			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
			throw ex;
		}
		catch (Error err) {
			ServletException ex = new NestedServletException("Handler processing failed", err);
			// Trigger after-completion for thrown exception.
			triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
			throw ex;
		}

		finally {
			// Clean up any resources used by a multipart request.
			if (processedRequest != request) {
				cleanupMultipart(processedRequest);
			}
		}
	}


  

猜你喜欢

转载自blog.csdn.net/wuxians/article/details/78049691