SpringMVC处理请求(一):FrameworkServlet

本文分析了请求从Servlet容器交到SpringMVC,到DispatcherServlet具体处理请求前的操作。介绍了HttpServletBean的创建工作,阐述Servlet处理过程,如根据请求类型路由,FrameworkServlet重写方法及处理PATCH请求。还说明了processRequest的功能,最后总结了FrameworkServlet处理请求的流程。

简介 分析请求从Servlet容器交到SpringMVC一直到DispatcherServlet具体处理请求之前都做了些什么

1. HttpServletBean
 主要参与了创建工作,并没有涉及到请求的处理
2. Servlet的处理过程
 首先从Servlet的service方法开始,然后在HttpServlet的service方法中根据请求的类型不同将请求路由到doGet、doHead、doPost、doPut、doDelete、doOptions、doTrace七种方法中;在FrameworkServlet中重写了除doHead,在service方法中增加了对PATCH类型请求的处理,其他类型的请求直接交给了父类进行处理;以POST请求为例,FrameworkServlet实现了HttpServlet中的doPost方法进行具体处理.

package org.springframework.web.servlet.FrameworkServlet;

  /**
    * Override the parent class implementation in order to intercept PATCH requests.
    */
   @Override
   protected void service(HttpServletRequest request, HttpServletResponse response)
   		throws ServletException, IOException {

   	HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
   	if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
   		processRequest(request, response);
   	}
   	else {
   	  //若是post请求,进入下面的doPost方法
   		super.service(request, response);
   	}
   }

  /**
    * 实现了HttpServlet的doPost方法
    */
   @Override
   protected final void doPost(HttpServletRequest request, HttpServletResponse response)
   		throws ServletException, IOException {
   		processRequest(request, response);
   }


   /**
    * Process this request, publishing an event regardless of the outcome.
    * <p>The actual event handling is performed by the abstract
    * {@link #doService} template method.
    */
   protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
   		throws ServletException, IOException {

   	long startTime = System.currentTimeMillis();
   	Throwable failureCause = null;
   	//获取LocaleContextHolder中原来保存的LocaleContext
   	LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
   	//获取当前请求的LocaleContext
   	LocaleContext localeContext = buildLocaleContext(request);

   	//获取RequestContextHolder中原来保存的RequestAttributes
   	RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
   	//获取当前请求的ServletRequestAttributes
   	ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

   	WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
   	asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

   	//将当前请求的LocaleContext和RequestAttributes设置到LocaleContextHolder和RequestContextHolder
   	initContextHolders(request, localeContext, requestAttributes);

   	try {
   		//实际处理请求入口,在DispatcherServlet中具体实现
   		doService(request, response);
   	}
   	catch (ServletException | IOException ex) {
   		failureCause = ex;
   		throw ex;
   	}
   	catch (Throwable ex) {
   		failureCause = ex;
   		throw new NestedServletException("Request processing failed", ex);
   	}

   	finally {
   		//恢复原来的LocaleContext和RequestAttributes设置到LocaleContextHolder和RequestContextHolder.因为在servlet外面可能还有别的操作,如Filter等
   		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");
   				}
   			}
   		}
   		//发布ServletRequestHandledEvent
   		publishRequestHandledEvent(request, response, startTime, failureCause);
   	}
   }

processRequest主要功能:
1)异步请求
2)调用doService方法具体处理请求
3)对LocaleContext(用于获取Locale)和RequestAttributes(用于管理requesthesession属性)的设置及恢复
4)处理完后发布ServletRequestHandledEvent消息

总结FrameworkServlet处理请求:
首先在service方法里添加了对PATCH的处理,并将所有需要自己处理的请求都集中到了processRequest方法进行统一处理,人后就是processRequest方法.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值