ReturnValueHandler
原理
目标方法执行完,会返回Person
对象
@Controller
public class ResponseTestController {
@ResponseBody
@GetMapping("/getperson")
public Person getPerson() {
Person person = new Person();
person.setUserName("张三");
person.setAge(23);
person.setBirth(new Date());
person.setPet(new Pet("小黄",6));
return person;
}
}
目标方法会返回一个返回值
返回值解析器可以解析目标方法的返回值
如果有返回值,就会调用handleReturnValue()
方法利用返回值处理器来处理返回值
handleReturnValue()
方法调用selectHandler()
方法,会根据返回值和返回值的类型,找到能够处理这个返回值的返回值处理器。然后利用这个找到返回值处理器,调用它的handleReturnValue()
方法来处理返回值
RequestResponseBodyMethodProcessor
这个返回值处理器可以处理标注了@ResponseBody
注解的目标方法的返回值。handleReturnValue()
方法会包装请求和响应的信息,调用writeWithMessageConverters()
方法,使用消息转换器进行写出操作
writeWithMessageConverters()
方法会进行内容协商,浏览器默认会以请求头的方式(Accept
字段)告诉服务器它能接受什么样的内容类型。
获取浏览器能接收的内容类型,以及服务器能生产的内容类型
双重循环进行匹配,决定能使用什么内容类型的数据
然后遍历所有的消息转换器,找到能处理这个内容类型的数据
遍历如下默认的消息转换器
MappingJackson2HttpMessageConverter
消息转换器可以将任何对象转为json
判断消息转换器能写,如果可以就调用write()
方法写出去
write()
方法会获取响应头,并添加内容类型字段的值,然后利用底层的jackson包将数据转为json
写出去
返回值处理器原理总结
- 返回值处理器会调用
supportsReturnType()
方法判断是否支持这种类型的返回值。 - 如果支持,返回值处理器就会调用
handleReturnValue()
方法进行处理。 - 而
RequestResponseBodyMethodProcessor
可以处理标注了@ResponseBody
注解的目标方法的返回值。
(1)调用writeWithMessageConverters()
方法将数据写为json
。
(2)进行内容协商,浏览器默认会以请求头的方式(Accept
字段)告诉服务器它能接受什么样的内容类型。
(3)服务器最终会根据自己自身的能力,决定服务器能生产出什么样内容类型的数据。
(4)SpringMVC会挨个遍历所有容器底层的HttpMessageConverter
,找出能够处理已经决定好的内容类型的数据。MappingJackson2HttpMessageConverter
消息转换器可以将任何对象转为json
,利用MappingJackson2HttpMessageConverter
将对象转为json
再写出去。