接着前一篇博客:SpringMVC:请求参数解析原理
测试方法:
@PostMapping("save")
@ResponseBody
public Person save(Person person){
return person;
}
上篇博客通过对SpringMVC断点跟踪,找到了请求参数解析是通过众多请求参数解析器处理的。而我们发现在RequestMappingHandlerAdapter类中的invokeHandlerMethod,会在invocableMethod加载众多参数解析器和返回值处理器。

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

HandlerMethodReturnValueHandler接口有两个方法:supportsReturnType和handleReturnValue
获取返回值处理器和处理返回值,跟请求参数解析器的源码很像,都是遍历所有的处理器,找到对应的的处理器,然后调用该处理器的处理方法。
因为我这里标注了@ResponseBody,所以由RequestResponseBodyMethodProcessor处理器进行处理,具体判断逻辑,这里就不看了,也比较简单。
我们关注的是它的handleRetureValue是怎么执行的?具体调用了writeWithMessageConverters方法来处理返回值。根据方法名,可以得出是通过MessageConverters消息转换器进行处理。

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

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


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

producibleTypes是后端能返回的类型:

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

mediaType找到后,重点来了。

消息转换器接口:主要功能就是将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方法
整个过程下来:MappingJackson2HttpMessageConverter可以将对象转为json,再将json写出去