从源码角度看spring mvc的请求处理过程

网友投稿 351 2023-08-02

从源码角度看spring mvc的请求处理过程

从源码角度看spring mvc的请求处理过程

在分析spring mvc源码之前,先看一张图:

请求处理的过程:

1.DispatcherServelt作为前端控制器,拦截request对象。

2.DispatcherServlet接收到request对象之后,查询HandlerMapping,得到一个HandlerExecutionChain对象。

3.DispatcherServlet将Handler对象交由HandlerAdapter(适配器模式的典型应用),调用相应的controller方法

4.Controller方法返回ModelAndView对象,DispatcherServlet将view交由ViewResolver进行解析,得到相应的视图。用model渲染视图。

5.返回响应结果。

整个过程的流程其实就是DispatcherServelt中doDispatch()方法的调用过程。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

//第一步拦截request对象,doDispatch()方法在doService()方法中被调用,request对象是经过处理的。

HttpServletRequest processedRequest = request;

HandlerExecutionChain mappedHandler = null;

boolean multipartRequestParsed = false;

WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

try {

ModelAndView mv = null;

Exception dispatchException = null;

try {

//和文件的上传和-有关系,判断请求的类型是否是multipart类型

processedRequest = checkMultipart(request);

multipartRequestParsed = (processedRequest != request);

// Determine handler for the current request.

//主要看这里,这里是得到HandlerExecutionChain的方法。关于Handler()方法向下看

mappedHandler = getHandler(processedRequest);

if (mappedHandler == null || mappedHandler.getHandler() == null) {

noHandlerFound(processedRequest, response);

return;

}

// Determine handler adapter for the current request.

//这里已经获取到HandlerExecutionChain对象,接下来就要获取HandlerAdapter对象,调用Handler对象的方法。

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// Process last-modified header, if supported by the handler

//有关浏览器缓存的设定(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()) {

logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);

}

if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {

return;

}

}

//pan'du

if (!mappedHandler.applyPreHandle(processedRequest, response)) {

return;

}

// Actually invoke the handler.

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

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

if (mappedHanRMvEKdler != null) {

mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);

}

}

else {

// Clean up any resources used by a multipart request.

if (multipartRequestParsed) {

cleanupMultipart(processedRequest);

}

}

}

}

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

//遍历HandlerMappingList对象(存储若干个HandlerMapping对象),不断调用,直到不为空为止,否则返回null

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) {

return handler;

}

}

return null;

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:小程序系统开发设计 - 为您打造独一无二的移动应用体验
下一篇:通过springboot+mybatis+druid配置动态数据源
相关文章

 发表评论

暂时没有评论,来抢沙发吧~