SpringBoot内容协商(Content Negotiation)
内容协商
在 HTTP 协议中,内容协商是一种机制,用于为同一 URI 提供资源不同的表示形式,以帮助用户代理指定最适合用户的表示形式(例如,哪种文档语言、哪种图片格式或者哪种内容编码)。[^1]
SpringBoot内容协商
- 基于请求头内容协商(默认开启)
- 客户端向服务端发送请求,携带HTTP标准的Accept请求头。
Accept
:application/json
、text/xml
、`text/yaml- 服务端根据客户端请求头期望的数据类型进行动态返回
- 基于请求参数内容协商(需要开启)
- 客户端发送请求
GET /projects/spring-boot?format=json
- 服务端匹配到
@GetMapping("/projects/spring-boot")
,根据参数协商,优先返回 json 类型数据【需要开启参数匹配设置】
开启参考内容协商设置
spring:
mvc:
contentnegotiation: # 内容协商
favor-parameter: true # 是否应该使用请求参数(默认为“format”)来确定请求的媒体类型。默认为false
parameter-name: format # 启用“favor-parameter”时使用的参数名称。不设置时使用“format”
代码示例
pom.xml
需要测试返回xml格式的数据,这里额外导入了
jackson-dataformat-xml
配置
点击查看代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atguigu</groupId>
<artifactId>boot3-04-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>boot3-04-web</name>
<description>boot3-04-web</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
bean
因为测试需要xml的返回结果,这里配置了@JacksonXmlRootElement,如果不需要可以不配置,json的返回结果SpringBoot默认是支持的。
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JacksonXmlRootElement
public class Person {
private Long id;
private String name;
private String email;
private Integer age;
}
controller
@Slf4j
@RestController
public class HelloController {
@GetMapping("/person")
public Person person(){
return Person.builder()
.id(1L)
.name("张三")
.email("110@gamil.com")
.age(18)
.build();
}
}
application.yml
spring:
mvc:
contentnegotiation: # 内容协商
favor-parameter: true # 是否应该使用请求参数(默认为“format”)来确定请求的媒体类型。默认为false
parameter-name: format # 启用“favor-parameter”时使用的参数名称。不设置时使用“format”
客户端请求
-
基于请求头内容协商
-
基于请求参数内容协商
参考:
[1] https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Content_negotiation
[2] https://www.yuque.com/leifengyang/springboot3/wp5l9qbu1k64frz1#haGAM
---------------
我每一次回头,都感觉自己不够努力,所以我不再回头。
---------------