SpringMVC:返回值处理器原理和MessageConverter原理

接着前一篇博客:SpringMVC:请求参数解析原理

测试方法:

@PostMapping("save")
@ResponseBody
public Person save(Person person){
    return person;
}

上篇博客通过对SpringMVC断点跟踪,找到了请求参数解析是通过众多请求参数解析器处理的。而我们发现在RequestMappingHandlerAdapter类中的invokeHandlerMethod,会在invocableMethod加载众多参数解析器和返回值处理器。

image-20210407101140756

image-20210407101743685

返回值处理器总共有15种:都实现了HandlerMethodReturnValueHandler接口

image-20210407101817983

HandlerMethodReturnValueHandler接口有两个方法:supportsReturnTypehandleReturnValue

获取返回值处理器和处理返回值,跟请求参数解析器的源码很像,都是遍历所有的处理器,找到对应的的处理器,然后调用该处理器的处理方法。

image-20210407102027816

因为我这里标注了@ResponseBody,所以由RequestResponseBodyMethodProcessor处理器进行处理,具体判断逻辑,这里就不看了,也比较简单。

我们关注的是它的handleRetureValue是怎么执行的?具体调用了writeWithMessageConverters方法来处理返回值。根据方法名,可以得出是通过MessageConverters消息转换器进行处理。

image-20210407102714530

那我们就要看MessageConverters消息转换器是如何工作的。

image-20210407103141996

断点继续往下走:媒体类型的判断

image-20210407103502646

image-20210407103619430

这里acceptableTypes是浏览器能接收的返回值类型:

image-20210407103653776

producibleTypes是后端能返回的类型:

image-20210407103732432

服务器会根据自身能力,决定生产出什么样的内容类型的数据mediaTypesToUse

image-20210407103942189

mediaType找到后,重点来了。

image-20210407104529831

消息转换器接口:主要功能就是将Class对象转换为MediaType类型的数据。

public interface HttpMessageConverter<T> {
	//是否能读
	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
	//是否能写
	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
	//获取所有支持转换的MediaType
	List<MediaType> getSupportedMediaTypes();
	//读操作
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;
	//写操作
	void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;

}

断点继续往下走,发现最终由MappingJackson2HttpMessageConverter这个类型来处理,写出操作用的是write方法

image-20210407105602565 image-20210407105910461

整个过程下来:MappingJackson2HttpMessageConverter可以将对象转为json,再将json写出去

原文地址:https://www.cnblogs.com/wwjj4811/p/14626838.html