SpringBoot Web源码分析(三) 响应处理源码分析

层层递进的关系来分析 SpringBoot 的Web模块源码

1. SpringBoot Web源码分析(一) 静态资源源码分析

2. SpringBoot Web源码分析(二) 请求处理源码分析

3. SpringBoot Web源码分析(三) 响应处理源码分析

4. SpringBoot Web源码分析(四) 视图解析器源码分析

5. SpringBoot Web源码分析(五),拦截器和文件上传

6. SpringBoot Web源码分析(六) 异常处理和Servlet组件

7. SpringBoot Web源码分析(七) 嵌入式服务器和定制化原理

1.3 响应处理

1.3.1 响应 JSON

相关依赖

    <dependency>
     <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
web场景自动引入了json场景
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-json</artifactId>
      <version>2.3.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>

通过 debug 模式下,我们能找到在底层有一个返回值解析器

1. 返回值解析器

在这里插入图片描述
在返回要返回的值之前,要经过多次进行检测,检测是否为空,是否为字符串等等,等确定是一个返回对象时,执行这个方法:

try {
			this.returnValueHandlers.handleReturnValue(
					returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
		}

进入找到真正执行的方法

	@Override
	public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
		// 找到哪个返回值处理器能处理,然后来进行处理
		HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
		if (handler == null) {
			throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
		}
		handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
	}

返回值处理器接口
在这里插入图片描述

RequestResponseBodyMethodProcessor  	
@Override
	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);
	}

第一个方法用来判断这个返回值处理器是否支持这个返回值

第二个方法就是当支持时,就会调用这个处理方法来进行处理

2. 返回值解析器原理
  1. 返回值处理器判断是否支持这种类型
  2. 返回值调用 handleReturnValue 方法来进行处理
  3. RequestResponseBodyMethodProcessor 可以处理@RequestBody 注解标注的请求
    1. 利用 MessageConverters 进行处理 将数据写为 JSON
      1. 内容协商(浏览器默认会以请求头的方式告诉服务器他能接受什么样的内容类型)
      2. 服务器最终根据自己自身的能力,决定服务器能生产出什么样内容类型的数据,
      3. SpringMVC会挨个遍历所有容器底层的 HttpMessageConverter ,看谁能处理?
    2. 得到MappingJackson2HttpMessageConverter可以将对象写为JSON
    3. 利用MappingJackson2HttpMessageConverter将对象转为JSON再写出去。

内容协商
在这里插入图片描述

1.3.2 SpringMVC 支持的返回值

ModelAndView
Model
View
ResponseEntity 
ResponseBodyEmitter
StreamingResponseBody
HttpEntity
HttpHeaders
Callable
DeferredResult
ListenableFuture
CompletionStage
WebAsyncTask@ModelAttribute 且为对象类型的
@ResponseBody 注解 ---> RequestResponseBodyMethodProcessor

1.3.3 HTTPMessageConverter原理

在这里插入图片描述

HttpMessageConverter: 看是否支持将 此 Class类型的对象,转为MediaType类型的数据。
例子:Person对象转为JSON。或者 JSON转为Person

默认的MessageConverter

在这里插入图片描述
0 - 只支持Byte类型的
1 - String
2 - String
3 - Resource
4 - ResourceRegion
5 - DOMSource.class \ SAXSource.class) \ StAXSource.class \StreamSource.class \Source.class
6 - MultiValueMap
7 - true
8 - true
9 - 支持注解方式xml处理的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_CX_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值