【SpringMvc执行流程】SpringMvc rest接口处理流程(十二)

spring mvc rest 处理流程

根据前面学习的处理流程整理了下

项目搭建

构建一个简单的spingboot项目,如下:

@RestController
public class HelloWorldController {
    @RequestMapping("/")
    public String index(@RequestParam int value) {
        return "index"+ value;
    }
}

此项目中只有一个简单的controller接收请求。下面启动项目请求接口,一步步debug走起。

dispatcherServlet

//伪代码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
 HandlerExecutionChain getHandler(processedRequest); //获取满足条件的handlerMethod
}
protected HandlerExecutionChain getHandler(HttpServletRequest request) {
        for (HandlerMapping hm : this.handlerMappings) {//通过循环遍历,匹配对应的HandlerMapping
            HandlerExecutionChain handler = hm.getHandler(request); //获取对应的handlerMethod
            if (handler != null) {
                return handler;
            }
}

当有请求过来时,执行doDispatch,通过调用getHandler获取请求对应的handlerMethod。debug时,可以在for循环中找到handlerMappings中匹配成功的是RequestMappingHandlerMapping。

//伪代码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
 HandlerExecutionChain  getHandler(processedRequest); //获取满足条件的handlerMethod
 HandlerAdapter getHandlerAdapter(HandlerExecutionChain.getHandler());//根据handlerMethod获取HandlerAdapter
}

当获取到包含handlerMethod的HandlerExecutionChain时,通过HandlerExecutionChain的handler获取HandlerAdapter。debug发现HandlerAdapter为RequestMappingHandlerAdapter。

HandlerAdapter

执行handle方法去执行具体的方法

//伪代码
ModelAndView invokeHandlerMethod(request, response, handlerMethod) {
  void ServletInvocableHandlerMethod.invokeAndHandle(webRequest, mavContainer);//解析参数和执行请求,返回结果。
  return getModelAndView(mavContainer, modelFactory, webRequest); //返回ModelAndView
}

handlerAdapter的意义在于分担DispatherServlet工作量和set一些必要的参数。这里handlerAdapter直接把任务委派给ServletInvocableHandlermethod。

ServletInvocableHandlermethod

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
            Object... providedArgs) throws Exception {

        Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);//解析参数和执行请求
        HandlerMethodReturnValueHandlerComposite.handleReturnValue(
                    returnValue, getReturnValueType(returnValue), mavContainer, webRequest);//处理结果

执行完controller方法后,进行对结果进行处理。

HandlerMethodReturnValueHandler

public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
      ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

   HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
   } //根据返回参数的类型进行不同的处理

如上述中,我们使用的是@RestController,由于restController中包含了@ResponseBody,所以这里采用

RequestResponseBodyMethodProcessor直接返回结果。

RequestResponseBodyMethodProcessor

public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
        ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
        throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {

    mavContainer.setRequestHandled(true);
    ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
    ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);

    // Try even with null return value. ResponseBodyAdvice could get involved.
    writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}

接口的处理流程大概就是这样的


文章作者: Ciwei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ciwei !
 上一篇
【MySQL】标准化安装教程 【MySQL】标准化安装教程
导读:本文主要介绍 CentOS 系统二进制安装 MySQL 5.7.23 版本的安装步骤,其他版本安装过程相似。 1.前置准备 卸载旧版MySQL 查看rpm包 rpm -qa|grep mysql 若有可用rpm -e卸载
2019-07-22
下一篇 
【SpringCloud学习】Feign捕获异常(Greenwich版) 【SpringCloud学习】Feign捕获异常(Greenwich版)
介绍feign不使用熔断器的时候捕获异常 实现ErrorDecoder获取抛出的异常 import com.fasterxml.jackson.databind.ObjectMapper; import feign.Response;
2019-07-21
  目录