【Web响应处理】ReturnValueHandler原理

Source

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写出去
在这里插入图片描述

返回值处理器原理总结

  1. 返回值处理器会调用supportsReturnType()方法判断是否支持这种类型的返回值。
  2. 如果支持,返回值处理器就会调用handleReturnValue()方法进行处理。
  3. RequestResponseBodyMethodProcessor可以处理标注了@ResponseBody注解的目标方法的返回值。
    (1)调用writeWithMessageConverters()方法将数据写为json
    (2)进行内容协商,浏览器默认会以请求头的方式(Accept字段)告诉服务器它能接受什么样的内容类型。
    (3)服务器最终会根据自己自身的能力,决定服务器能生产出什么样内容类型的数据。
    (4)SpringMVC会挨个遍历所有容器底层的HttpMessageConverter,找出能够处理已经决定好的内容类型的数据。MappingJackson2HttpMessageConverter消息转换器可以将任何对象转为json,利用MappingJackson2HttpMessageConverter将对象转为json再写出去。