SpringBoot内容协商(Content Negotiation)

内容协商

在 HTTP 协议中,内容协商是一种机制,用于为同一 URI 提供资源不同的表示形式,以帮助用户代理指定最适合用户的表示形式(例如,哪种文档语言、哪种图片格式或者哪种内容编码)。[^1]

SpringBoot内容协商

  1. 基于请求头内容协商(默认开启)
  • 客户端向服务端发送请求,携带HTTP标准的Accept请求头。Accept: application/jsontext/xml、`text/yaml
  • 服务端根据客户端请求头期望的数据类型进行动态返回
  1. 基于请求参数内容协商(需要开启)
  • 客户端发送请求 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. 基于请求头内容协商

  2. 基于请求参数内容协商

参考:
[1] https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Content_negotiation
[2] https://www.yuque.com/leifengyang/springboot3/wp5l9qbu1k64frz1#haGAM

posted @ 2023-10-25 00:47  雨中遐想  阅读(70)  评论(0编辑  收藏  举报