内容协商
2023年11月17日大约 4 分钟约 763 字
基本介绍
- 根据客户端接收能力不同,SpringBoot 返回不同媒体类型的数据。
- 比如:客户端 Http 请求 Accept: application/xml 则返回 xml 数据,客户端 Http 请求 Accept: application/json 则返回 json 数据。
- 如下图:


应用实例
使用Postman发送Http请求,根据请求头不同,返回对应的json数据或者xml数据,如上图。
修改pom.xml
<!-- 引入支持返回 xml 数据格式 -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
使用Postman发出不同的Http Header,可以看到返回对应的数据格式( 测试前,请重启项目)

注释掉pom.xml
<!-- 引入支持返回 xml 数据格式 -->
<!--<dependency>-->
<!-- <groupId>com.fasterxml.jackson.dataformat</groupId>-->
<!-- <artifactId>jackson-dataformat-xml</artifactId>-->
<!--</dependency>-->
重新启动项目,修改 Accept再次请求
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

服务器此时不能返回xml数据,但是因为内容协商,没有xml就返回json数据。
注意事项和使用细节
- Postman 可以通过修改 Accept 的值,来返回不同的数据格式。
- 对于浏览器,我们无法修改其 Accept 的值,怎么办? 解决方案:开启支持基于请求参数 的内容协商功能。
(1)修改 application.yml,开启基于请求参数的内容协商功能。
spring:
mvc:
# static-path-pattern: /lzwres/**
hiddenmethod:
filter:
enabled: true #启用了 HiddenHttpMethodFilter,开启页面表单的 Rest 功能
view: # 配置视图解析器
suffix: .html
prefix: / #这里是需要注意 prefix 需要和当前的 static-path-pattern 一致
contentnegotiation:
favor-parameter: true #开启基于请求参数的内容协商功能
web:
resources:
# 如果配置了 static-locations,原来的访问路径就被覆盖,如果需要保留,需要再指定一下
static-locations: ["classpath:/lzwimg/","classpath:/META-INF/resources/",
"classpath:/public/", "classpath:/static/","classpath:/resources/"] # 修改静态资源访问的路径


(2)指定一个内容协商的参数名
spring:
mvc:
# static-path-pattern: /lzwres/**
hiddenmethod:
filter:
enabled: true #启用了 HiddenHttpMethodFilter,开启页面表单的 Rest 功能
view: # 配置视图解析器
suffix: .html
prefix: / #这里是需要注意 prefix 需要和当前的 static-path-pattern 一致
contentnegotiation:
favor-parameter: true #开启基于请求参数的内容协商功能
parameter-name: lzwformat #指定一个内容协商的参数名
web:
resources:
# 如果配置了 static-locations,原来的访问路径就被覆盖,如果需要保留,需要再指定一下
static-locations: ["classpath:/lzwimg/","classpath:/META-INF/resources/",
"classpath:/public/", "classpath:/static/","classpath:/resources/"] # 修改静态资源访问的路径

(3)注意,参数 format 是规定好的,在开启请求参数的内容协商功能后,SpringBoot 底层 ParameterContentNegotiationStrategy 会通过 format 来接收参数,然后返回对应的媒体类型/ 数据格式,当然 format=xx 这个 xx 媒体类型/数据格式 是 SpringBoot 可以处理的才行,不能乱写。