当前位置: 首页 > article >正文

SpringBoot2:请求处理原理分析-接口方法的返回值处理(returnValueHandlers)

文章目录

  • 一、知识回顾
  • 二、测试接口
  • 三、源码解读
  • 四、逻辑梳理

一、知识回顾

前面,我们学习了,一个请求过来,先经过filter组件,判断restful风格接口的请求类型。
然后,通过HandlerMapping找到处理该请求的接口。
接着,进入接口方法的参数解析环节,这里主要学习了参数解析器(argumentResolvers)
和数据类型转换服务(Converters),将请求的实参值与方法的形参绑定上。
然后,执行接口方法主体。

那么,方法体执行完后,就到了return环节。就是返回值处理环节。
这一篇,我们就来看一下返回值处理的源码逻辑。

二、测试接口

接下来,我们就对@ResponseBody标注的接口,进行返回值原理探究。

    @ResponseBody  //利用返回值处理器里面的消息转换器进行处理
    @GetMapping(value = "/test/person")
    public Person getPerson(){
        Person person = new Person();
        person.setAge(28);
        person.setBirth(new Date());
        person.setUserName("zhangsan");
        return person;
    }

在这里插入图片描述
我们知道,@ResponseBody标注的接口,都会给页面返回json数据。

三、源码解读

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
在这里插入图片描述
这里,我们看到了返回值处理器,默认是15个。
在这里插入图片描述
中间的其他步骤,我直接跳过了,进入关键代码
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite#handleReturnValue
在这里插入图片描述
这里,第一步,先获取能处理这个接口返回值类型的返回值处理器。这个获取逻辑,就是从15个返回值处理器中,循环遍历,找到具体的返回值处理器。
在这里插入图片描述
我们查看下返回值处理器接口规范
在这里插入图片描述
两个方法
supportsReturnType:判断方法
handleReturnValue:处理逻辑
会发现,这个设计模式和参数解析器一样思路。
断点放行下一步,得到@ResponseBody标注的接口的返回值处理器是:
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor#handleReturnValue
在这里插入图片描述
这个返回值处理方法,我们可以看到,最后一行的方法名
利用消息转换器写数据。
所以,返回值处理器,需要依赖底层的消息转换器

我们在看下消息转换器的具体逻辑
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters(T, org.springframework.core.MethodParameter, org.springframework.http.server.ServletServerHttpRequest, org.springframework.http.server.ServletServerHttpResponse)
在这里插入图片描述
这里又出现一个新的组件,媒体类型
媒体类型:就是请求接口的客户端,如浏览器,postman,传给接口的Accept参数值。
目的就是告诉服务器接口,我能接收那些类型的返回值。
让springboot根据权重,选择最佳返回值返回给浏览器。
在这里插入图片描述
那么,这里就涉及到springboot接口能生产那些类型的返回值。
然后,才能选择最优解。
这个选择过程,就叫内容协商
内容协商:说简单点,就是,浏览器和服务器商量,用什么样的结构数据返回给浏览器。

继续往下看
在这里插入图片描述
这里,我们获取到了,所有浏览器可以接收的返回值类型,和所有springboot可以生产的返回值类型
接下来,就要利用嵌套for循环确定出最终返回值类型。
在这里插入图片描述
在这里插入图片描述
经过循环处理后,得到14个可以返回的数据类型,并对这14个类型进行了权重排序。

m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json;q=0.8', given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.7, */*;q=0.8] and supported [application/json, application/*+json, application/json, application/*+json]

从日志看出,最终协商结果就是,返回json数据格式。

内容协商阶段结束后,就要利用消息转换器(HttpMessageConverter),进行返回值数据格式化了。
Java对象,处理成json结构,返回给浏览器。
在这里插入图片描述
在这里插入图片描述
springboot默认的消息转换器有10中。
那么,哪个消息转换器负责处理json返回值了?

这里,我们依然看一下消息转换器接口规范
在这里插入图片描述
有5个待实现的方法。
在这里插入图片描述
最终,是
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
来处理json返回类型的数据。
调用对应的write方法,写出json数据给浏览器。

到这里,返回值处理的过程和主要组件介绍完毕。

四、逻辑梳理

简单来说就是以下几步:

首先,请求过来后,DispatcherServlet中,会确定返回值处理器returnValueHandlers
默认有15种。

然后,具体的返回值处理器来进行处理。
返回值处理器中的逻辑如下

1、进行内容协商。
获取客户端发过来的能接收的所有媒体类型(MediaType)。
评估自己能生产的所有数据类型(ProducibleMediaTypes)

springboot默认是从requestHeaders中,获取Accept参数值,作为媒体类型,进行内容协商。
其实,也可以从参数中获取。
后面给出案例。

2、找到具体的消息转换器(HttpMessageConverter)。
springboot默认配置了10种消息转换器。
Java对象write给浏览器。


http://www.kler.cn/a/299046.html

相关文章:

  • 通过阿里云 Milvus 与 PAI 搭建高效的检索增强对话系统
  • 【蓝桥杯】43696.小数第n位
  • 林子雨-大数据课程实验报告(一)
  • #渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
  • outlook smtp 发送邮件
  • excel 使用vlook up找出两列中不同的内容
  • Redis 入门 - 五大基础类型及其指令学习
  • 【安卓13 源码】Input子系统(3) - EventHub增加设备的流程
  • C++ | Leetcode C++题解之第398题随机数索引
  • excel无法保存文件
  • 速盾:普通cdn和高防cdn差别在哪里?
  • 小程序事件函数传参
  • 2024版保姆级Anaconda+pycharm安装(中文)及环境配置教程
  • Qt C++ Udp相关知识学习(一)
  • javase复习day22集合进阶
  • tekton pipeline workspaces
  • 从虚拟现实到元宇宙:Facebook引领未来社交的下一步
  • 算法练习题21——卡片(模拟)
  • ubuntu ifconfig只有lo
  • Unexpected token ‘o‘, “[object Obj“... is not valid JSON 报错原因解释
  • larave5.8记录运行时产生的所有sql
  • 数据结构应用实例(四)——最小生成树
  • 性能测试 —— docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台!
  • Flask session cookie 失效在Safari中的解决方法
  • 《OpenCV计算机视觉》—— 图像金字塔
  • 记MySQL查询视图出现字符集编码不一致问题