?以下是我测试的请求
@Controller
public class ResponseTestController {
@ResponseBody
@GetMapping("/test/person")
public Person getPerson(){
Person person = new Person();
person.setAge(4);
person.setBirth(new Date());
person.setUserName("zhangsan");
return person;
}
}
我们从这里开始分析,invokeForRequest()是处理请求并得到返回值,?
if (returnValue == null) :此时返回值不为空
else if (StringUtils.hasText(getResponseStatusReason())):判断是否有返回失败的原因
此时会调用this.returnValueHandlers.handleReturnValue(returnValue,getReturnValueType(returnValue), mavContainer, webRequest)处理返回值
?进入handleReturnValue,第一步是寻找合适的处理器,第二步是用处理器处理?
进入selectHandler,
isAsyncReturnValue(value, returnType):是不是异步返回值
?进入isAsyncReturnValue,在15个处理器里进行寻找,最终返回false
?
?
?返回值处理器原理:
1、返回值处理器判断是否支持这种类型返回值 supportsReturnType
2、返回值处理器调用 handleReturnValue 进行处理
进入 handler.supportsReturnType(returnType),下图是第一个处理器判断的方法,通过比较是不是ModelAndView类型判断?
?最终:RequestResponseBodyMethodProcessor 可以处理返回值标了@ResponseBody 注解的
得到处理器之后,进入handle.handleReturnValue方法,这是最终处理返回值的方法
writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage):使用消息转换器进行写出操作,利用 MessageConverters 进行处理 将数据写为json
?进入writeWithMessageConverter,首先判断是不是字符串类型,不是进入else,进入else语句拿到person对象和类型,目标类型
?
if (isResourceType(value, returnType)):判断是不是资源类型, acceptableTypes:浏览器能接受的类型 producibleTypes:服务器能生产的类型?
两个for循环进行匹配
?
??HttpMessageConverter: 看是否支持将 此 Class类型的对象,转为MediaType类型的数据。
例子:Person对象转为JSON。或者 JSON转为Person
?
?进入convert.canwrite可查看各种解析器支持什么类型
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处理的。
?
?最终得到的解析器是MappingJackson2HttpMessageConverter
genericConverter.write(body, targetType, selectedMediaType, outputMessage):写json数据
?
?进入write方法,首先是添加响应头,然后进入else语句,通过writeInternal操作
?
?
返回值解析器原理:
- 1、返回值处理器判断是否支持这种类型返回值 supportsReturnType
- 2、返回值处理器调用 handleReturnValue 进行处理
- 3、RequestResponseBodyMethodProcessor 可以处理返回值标了@ResponseBody 注解的。
-
- 1. 利用 MessageConverters 进行处理 将数据写为json
-
-
- 1、内容协商(浏览器默认会以请求头的方式告诉服务器他能接受什么样的内容类型)
- 2、服务器最终根据自己自身的能力,决定服务器能生产出什么样内容类型的数据,
-
-
- 3、SpringMVC会挨个遍历所有容器底层的 HttpMessageConverter ,看谁能处理?
-
-
-
- 1、得到MappingJackson2HttpMessageConverter可以将对象写为json
- 2、利用MappingJackson2HttpMessageConverter将对象转为json再写出去。
|