详述SpringMVC请求处理过程

1、 点击“查看”链接,向Web服务器发送/userinfo/toView.do请求;
DispatcherServlet接受请求
2、 执行DispatcherServlet类service(HttpServletRequest request, HttpServletResponse response)方法,该方法源自于其父类FrameworkServlet,代码如下:

@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {

	HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
	if (HttpMethod.PATCH == httpMethod || httpMethod == null) {
		processRequest(request, response);
	}
	else {
		super.service(request, response);
	}
}

3、 执行HttpServlet类service(HttpServletRequest req, HttpServletResponse resp)方法,代码如下:

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException{
	String method = req.getMethod();
		
	if (method.equals(METHOD_GET)) {
	long lastModified = getLastModified(req);
	         if (lastModified == -1) {
	             // servlet doesn't support if-modified-since, no reason
	             // to go through further expensive logic
	             doGet(req, resp);
	         } else {
	             long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
	             if (ifModifiedSince < lastModified) {
	                 // If the servlet mod time is later, call doGet()
	                 // Round down to the nearest second for a proper compare
	                 // A ifModifiedSince of -1 will always be less
	                 maybeSetLastModified(resp, lastModified);
	                 doGet(req, resp);
	             } else {
	                 resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
	             }
	         }
			
	     } else if (method.equals(METHOD_HEAD)) {
	         long lastModified = getLastModified(req);
	         maybeSetLastModified(resp, lastModified);
	         doHead(req, resp);
			
	     } else if (method.equals(METHOD_POST)) {
	         doPost(req, resp);
	         
	     } else if (method.equals(METHOD_PUT)) {
	         doPut(req, resp);
	         
	     } else if (method.equals(METHOD_DELETE)) {
	         doDelete(req, resp);
	         
	     } else if (method.equals(METHOD_OPTIONS)) {
	         doOptions(req,resp);
	         
	     } else if (method.equals(METHOD_TRACE)) {
	         doTrace(req,resp);
	         
	     } else {
	         //
	         // Note that this means NO servlet supports whatever
	         // method was requested, anywhere on this server.
	         //
			
	         String errMsg = lStrings.getString("http.method_not_implemented");
	         Object[] errArgs = new Object[1];
	         errArgs[0] = method;
	         errMsg = MessageFormat.format(errMsg, errArgs);
	         
	         resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
	     }
}

4、 执行DispatcherServlet类doGet(HttpServletRequest request, HttpServletResponse response)方法,该方法源自于其父类FrameworkServlet,代码如下:

@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
	
	processRequest(request, response);
}

5、 执行DispatcherServlet类processRequest(HttpServletRequest request, HttpServletResponse response)方法,该方法源自于其父类FrameworkServlet,代码如下:

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
      
	 long startTime = System.currentTimeMillis();
	 Throwable failureCause = null;
     
	 LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
	 LocaleContext localeContext = buildLocaleContext(request);
      
	 RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
	 ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
      
	 WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
	 asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
      
	 initContextHolders(request, localeContext, requestAttributes);
      
	 try {
		 doService(request, response);
	 }
	 catch (ServletException ex) {
		 failureCause = ex;
		 throw ex;
	 }
	 catch (IOException ex) {
		 failureCause = ex;
		 throw ex;
	 }
	 catch (Throwable ex) {
		 failureCause = ex;
		 throw new NestedServletException("Request processing failed", ex);
	 }
      
	 finally {
		 resetContextHolders(request, previousLocaleContext, previousAttributes);
		 if (requestAttributes != null) {
			 requestAttributes.requestCompleted();
		 }
          
		 if (logger.isDebugEnabled()) {
			 if (failureCause != null) {
				 this.logger.debug("Could not complete request", failureCause);
			 }
			 else {
				 if (asyncManager.isConcurrentHandlingStarted()) {
					 logger.debug("Leaving response open for concurrent processing");
				 }
				 else {
					 this.logger.debug("Successfully completed request");
				 }
			 }
		 }
           
		 publishRequestHandledEvent(request, response, startTime, failureCause);
	 }
}

6、 执行DispatcherServlet类doService(HttpServletRequest request, HttpServletResponse response)方法,该方法源自于其父类FrameworkServlet,代码如下:

@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
	if (logger.isDebugEnabled()) {
		String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
		logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
				" processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
	}
       
	// Keep a snapshot of the request attributes in case of an include,
	// to be able to restore the original attributes after the include.
	Map<String, Object> attributesSnapshot = null;
	if (WebUtils.isIncludeRequest(request)) {
		attributesSnapshot = new HashMap<String, Object>();
		Enumeration<?> attrNames = request.getAttributeNames();
		while (attrNames.hasMoreElements()) {
			String attrName = (String) attrNames.nextElement();
			if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
				attributesSnapshot.put(attrName, request.getAttribute(attrName));
			}
		}
	}
     
	// Make framework objects available to handlers and view objects.
	request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
	request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
	request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
	request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
     
     FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
	if (inputFlashMap != null) {
		request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
	}
	request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
	request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
     
	try {
		doDispatch(request, response);
	}
	finally {
		if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
			// Restore the original attribute snapshot, in case of an include.
			if (attributesSnapshot != null) {
				restoreAttributesAfterInclude(request, attributesSnapshot);
			}
		}
	}
}

7、执行DispatcherServlet 类doDispatch(request, response)方法,代码如下:

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());//为当前请求确定Handler适配器,mappedHandler.getHandler()返回HandlerMethod对象
              
		     // 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()) {
					logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
				}
				if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
					return;
				}
			}
              
			if (!mappedHandler.applyPreHandle(processedRequest, response)) {//执行拦截器preHandle方法
				return;
			}
              
		     // Actually invoke the handler.
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//执行Handler方法,ha的值是RequestMappingHandlerAdapter类型的变量,执行其handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod)
              
		    if (asyncManager.isConcurrentHandlingStarted()) {
				return;
			}
              
			applyDefaultViewName(processedRequest, mv);
			mappedHandler.applyPostHandle(processedRequest, response, mv);//执行拦截器postHandle方法
		} 
		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);
		}
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);//处理Handler返回结果
	}
	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 afterCompletion
			if (mappedHandler != null) {
				mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
			}
		}
		 else {
			// Clean up any resources used by a multipart request.
			if (multipartRequestParsed) {
				cleanupMultipart(processedRequest);
			}
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值