目录
一、数据响应原理
如何响应数据?
最基本的用法:在控制器方法上加@ResponseBody注解,方法返回值就是返回给浏览器的json数据。
Springboot是如果解析返回值并返回json数据的呢?
使用了返回值处理器:HandlerMethodReturnValueHandler
- 1、返回值处理器判断是否支持这种类型返回值 supportsReturnType
- 2、返回值处理器调用 handleReturnValue 进行处理,下面就是处理不同类型返回值用到的不同类型的处理器:
- 3、RequestResponseBodyMethodProcessor 可以处理返回值标了@ResponseBody 注解的方法返回值。
- 4.接下来利用 MessageConverters 进行处理将数据写为json,
4.1、内容协商(浏览器默认会以请求头的方式告诉服务器他能接受什么样的内容类型)
4.2、SpringMVC会挨个遍历所有容器底层的 HttpMessageConverter ,看谁能处理?
4.3、服务器最终根据自己自身的能力,决定服务器能生产出什么样内容类型的数据,
4.4、得到MappingJackson2HttpMessageConverter可以将对象写为json返回
MessageConverter规范:
HttpMessageConverter: 看是否支持将此 Class类型的对象,转为MediaType类型的数据。
例子:Person对象转为JSON。或者 JSON转为Person
默认的MessageConverter:
二、内容协商
根据客户端接收能力不同,返回不同媒体类型的数据
2.1 开启浏览器参数方式内容协商功能
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
spring:
contentnegotiation:
favor-parameter: true #开启请求参数内容协商模式
这样就可以在浏览器发送请求时指定可以接受的参数类型了,例如:
http://localhost:8080/test/person?format=json
http://localhost:8080/test/person?format=xml
2.2 内容协商原理
contentNegotiationManager用于进行内容协商
- 1、判断当前响应头中是否已经有确定的媒体类型(MediaType)
- 2、获取客户端支持接收的内容类型。
有两种策略:
1.参数(开启内容协商,在url后面加上客户端期望接收的类型)
2.请求头(获取客户端Accept请求头字段)
默认使用基于请求头的策略
- 3、遍历循环所有当前系统的 MessageConverter,看谁支持操作这个对象
- 4、找到合适的converter,把converter支持的媒体类型统计出来(有优先级)
例如客户端需要【application/xml】。而服务端可提供【10种、json、xml】
-
5、调用最佳匹配媒体类型的converter进行转化 。