重学SpringBoot3-内容协商机制

news2024/11/15 11:13:49

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-内容协商机制

  • ContentNegotiationConfigurer接口
  • 配置内容协商
    • URL参数
    • Accept头
    • 使用Url扩展名
  • 自定义内容协商格式
    • 步骤1: 注册自定义媒体类型
    • 步骤2: 实现`HttpMessageConverter`接口
    • 步骤3: 使用自定义`HttpMessageConverter`
  • 注意点

在 Spring Boot 3 中,内容协商(Content Negotiation)是一个非常重要的概念,特别是在构建 RESTful API 时。内容协商机制允许客户端和服务器就如何交换资源的数据格式达成协议。简单来说,它允许客户端通过请求头指定它们希望接收响应的格式(如 JSON,XML 等),服务器基于这些信息来决定以什么格式返回数据。

ContentNegotiationConfigurer接口

org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer

ContentNegotiationConfigurer 是 Spring 框架中的一个接口,用于自定义内容协商策略,主要通过以下几种方式来实现:

  1. URL参数: 通过 URL 参数来指定响应格式,例如,?format=json
  2. Accept头: 通过 Accept 请求头来指定希望接收的响应类型,这是HTTP规范推荐的方式。
  3. 扩展名: 通过 URL 的扩展名来指定响应的格式。例如,.json 表示希望响应为 JSON 格式,.xml 表示希望响应为 XML 格式。

配置内容协商

在 Spring Boot 3 中,你可以在 application.propertiesapplication.yml 文件中进行基本的内容协商配置:

# 开启基于请求参数的内容协商功能,默认此功能不开启
spring.mvc.contentnegotiation.favor-parameter=true
# 指定内容协商时使用的参数名。默认是 format
spring.mvc.contentnegotiation.parameter-name=mediaType
# 用于设置支持的内容协商(Content Negotiation)的媒体类型
spring.mvc.contentnegotiation.media-types.json=application/json
spring.mvc.contentnegotiation.media-types.xml=application/xml

或者通过配置类来实现更复杂的逻辑,没错,就是之前讲过的通过重新 WebMvcConfigurer 接口方法实现自定义配置:

public interface WebMvcConfigurer {
    default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    }
    
    // 其他方法
}

以下是一个示例,演示如何通过配置类来配置内容协商策略:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer
            .favorParameter(true)
            .parameterName("mediaType")
            .ignoreAcceptHeader(false)
            .useRegisteredExtensionsOnly(false)
            .defaultContentType(MediaType.APPLICATION_JSON)
            .mediaType("json", MediaType.APPLICATION_JSON)
            .mediaType("xml", MediaType.APPLICATION_XML);
    }
}

在这个配置中:

  • favorParameter(true):允许使用 URL 参数进行内容协商。
  • parameterName("mediaType"):指定 URL 参数的名称。
  • ignoreAcceptHeader(false):不忽略 Accept 头,即同时支持Accept头和URL参数。
  • useRegisteredExtensionsOnly(false):不仅仅基于已注册的扩展进行格式匹配。
  • defaultContentType(MediaType.APPLICATION_JSON):设置默认的响应类型为JSON。
  • mediaType("json", MediaType.APPLICATION_JSON)mediaType("xml", MediaType.APPLICATION_XML):注册 URL 扩展名到 MIME 类型的映射。

注意,如果要支持输出 XML 需要 pom 文件引入 jackson 包:

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>

controller代码

URL参数

需要携带查询字符串 ?mediaType=

json格式

xml格式

Accept头

修改请求头使用 postman 或者 apifox 工具。

json格式

xml格式

使用Url扩展名

从Spring Framework 5.3开始,官方推荐使用其他内容协商机制(如请求头Accept)而非扩展名,因为路径扩展可能会引起一些安全和使用上的问题。因此,在实际应用中,建议评估使用扩展名方式的必要性。

配置了基于扩展名的内容协商,配置文件已经不支持这种配置,所有改成新建配置类的方式:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer
                .favorPathExtension(true)
                .favorParameter(false)
                .ignoreAcceptHeader(false)
                .useRegisteredExtensionsOnly(true)
                .mediaType("json", MediaType.APPLICATION_JSON)
                .mediaType("xml", MediaType.APPLICATION_XML);
    }
}

配置

json格式

xml格式

自定义内容协商格式

自定义内容协商格式主要涉及到两个方面:一是自定义支持的媒体类型(Media Types),二是自定义对这些媒体类型的处理。

在 Spring Boot 3 中,自定义内容协商格式通常需要以下几个步骤:

  1. 注册自定义媒体类型:你可以通过配置类来注册自定义的媒体类型,让 Spring MVC 知道你打算支持哪些额外的格式。
  2. 实现 HttpMessageConverter 接口:对于每种你想支持的媒体类型,你需要提供一个相应的HttpMessageConverter实现,用于序列化和反序列化数据。
  3. 配置 Spring MVC 以使用你的自定义 HttpMessageConverter:最后,你需要在 Spring MVC 配置中注册你的 HttpMessageConverter 实现,以确保Spring MVC 会使用它们进行请求和响应的处理。

步骤1: 注册自定义媒体类型

假设你想添加对 application/yaml 这种媒体类型的支持,首先需要在配置类中注册这种媒体类型:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.mediaType("yaml", MediaType.valueOf("application/x-yaml"));
    }
}

或者使用配置文件:

spring.mvc.contentnegotiation.media-types.yaml=application/x-yaml

还需要引入 Jackson 库的 YAML 数据格式支持:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
</dependency>

步骤2: 实现HttpMessageConverter接口

接下来,需要创建一个 HttpMessageConverter 实现,用于处理 YAML 格式的数据。这里需要实现 readwrite 方法,分别用于反序列化和序列化数据。例如,使用 YamlMapper(这是一个假设的类,实际上你可能需要使用例如SnakeYAML之类的库):

package com.coderjia.springboot304web.config;

import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;

/**
 * @author CoderJia
 * @create 2024/3/9 下午 10:32
 * @Description
 **/
public class YamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {

    private final YAMLMapper yamlMapper = new YAMLMapper();

    public YamlHttpMessageConverter() {
        super(MediaType.valueOf("application/x-yaml"));
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        // 这里简化了实现,实际上你可能需要更复杂的逻辑来决定你的converter支持哪些类
        return true;
    }

    @Override
    protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        // 从HttpInputMessage中读取并解析YAML格式的数据
        return yamlMapper.readValue(inputMessage.getBody(), clazz);
    }

    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        // 将给定的对象写入HttpOutputMessage的body中
        yamlMapper.writeValue(outputMessage.getBody(), object);
    }
}

步骤3: 使用自定义HttpMessageConverter

最后,需要在 Spring MVC 配置中注册这个新的 HttpMessageConverter。这通常是在一个配置类中完成,通过重写 configureMessageConverters方法:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.mediaType("yaml", MediaType.valueOf("application/x-yaml"));
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new YamlHttpMessageConverter());
    }

}

这样,当客户端请求以 application/x-yaml 格式接收数据时(比如,通过设置Accept: application/x-yaml头),Spring MVC 就会使用你的 YamlHttpMessageConverter 来序列化响应数据为YAML格式:

yaml格式

注意点

内容协商的配置和实现方式可能因 Spring Boot 版本的不同而略有变化。上述示例适用于 Spring Boot 3,但在实际应用中,还需要根据具体的需求和环境来调整配置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1515922.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI实战:借助Python与PaddleOCR,实现高精度文本检测与识别

1、引言 欢迎来到今天的教程&#xff1a;“驾驭PaddleOCR&#xff0c;解锁Python文字识别新技能”。在本篇文章中&#xff0c;我们将手把手教你如何安装及使用这款强大的Python库&#xff0c;轻松应对各类图像中的文字识别问题。 2、安装PaddleOCR 首先确保你的环境中已安装…

苹果电脑下载crossover对电脑有影响吗 crossover mac 好用吗CrossOver虚拟机 CrossOver打游戏

苹果电脑下载crossover对电脑有影响吗&#xff1f; 在苹果电脑下载安装crossover对电脑没有什么影响&#xff0c;并且可以解决macOS系统不能安装Windows应用程序的问题。相较于虚拟机和双系统而言&#xff0c;crossover安装软件更简单&#xff0c;占用内存也更小。下面我们来看…

Css基础——精灵图(sprites)和字体图标

1、精灵图 1.1、精灵图的由来 一个网页中往往会应用很多小的背景图像作为修饰&#xff0c;当网页中的图像过多时&#xff0c;服务器就会频繁地接收和发送 请求图片&#xff0c;造成服务器请求压力过大&#xff0c;这将大大降低页面的加载速度。 因此&#xff0c;为了有效地减…

可行性研究报告模板

1业务需求可行性分析 2技术可行性分析 2.1规范化原则 2.2高度的兼容性和可移植性 2.3人性化、适用性 2.4标准化统一设计原则 2.5先进安全可扩展性原则 3开发周期可行性分析 4人力资源可行性分析 5成本分析 6收益分析 7结论 软件项目全套资料获取下载&#xff1a;软件开发全套资…

链路聚合练习

下面的接口都改为Etherent [LSW1]int Eth-Trunk 1 创建一个eth-trunk 1[LSW1-Eth-Trunk1]int g0/0/1[LSW1-GigabitEthernet0/0/1]eth-trunk 1 将接口0/0/1加入eth-trunk 1[LSW1-GigabitEthernet0/0/1]int g0/0/2[LSW1-GigabitEthernet0/0/2]eth-trunk 1[LSW1-GigabitEthernet…

CAQ六西格玛绿带认证流程:从能力考试到评价全解析

六西格玛绿带认证&#xff0c;作为质量管理领域的一个重要里程碑&#xff0c;对于专业人士来说是一项极具价值的认证。张驰咨询将详细解读这一流程&#xff0c;包括理论知识考试、项目实践能力评价&#xff0c;以及期满换证的相关细节。 一、理论知识考试 六西格玛绿带的理论…

OpenAI机器人,一出手就是王炸

「借助 OpenAI 的能力&#xff0c;Figure 01 现在可以与人全面对话了&#xff01;」 本周三&#xff0c;半个硅谷都在投的明星机器人创业公司Figure&#xff0c;发布了自己第一个 OpenAI 大模型加持的机器人 demo。 这家公司在 3 月 1 日刚刚宣布获得 OpenAI 等公司的投资&…

论文阅读——VSA

VSA: Learning Varied-Size Window Attention in Vision Transformers 方法&#xff1a; 给定输入特征X&#xff0c;VSA首先按照基线方法的例程&#xff0c;将这些标记划分为几个窗口Xw&#xff0c;窗口大小为预定义的w。我们将这些窗口称为默认窗口&#xff0c;并从默认窗口中…

(一)搭建Android Studio开发环境

一、JDK 1、下载 2、安装 双击进行安装&#xff0c;修改安装路径为&#xff1a;D:\Java\jdk-17.0.4.1即可&#xff0c;安装完成后目录如下&#xff1a; 配置环境变量 3、测试 WinR&#xff0c;输入cmd&#xff0c;按Enter后&#xff0c;键入&#xff1a;java --version&…

面试经典-18-合并两个有序链表

题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 解 class Solution {// 成功public ListNode mergeTwoLists(ListN…

探索世界的第一步:新生儿抬头指南

引言&#xff1a; 新生儿的抬头能力是他们发展早期的重要里程碑之一。这不仅是对颈部肌肉的锻炼&#xff0c;更是对视觉和感觉系统的发展的重要促进。在这个阶段&#xff0c;父母的关注和引导至关重要&#xff0c;以帮助宝宝安全地探索和发展。 1. 激发兴趣&#xff1a; 从宝宝…

matlab调用nlopt时向目标函数中传入数据的案例

matlab调用nlopt时向目标函数中传入数据的案例&#xff0c;如代码所示&#xff1a; clc,clear,close allopt.algorithm NLOPT_LN_AUGLAG; opt.lower_bounds -10; opt.upper_bounds 10; opt.min_objective (x) goal_function(x,[1,2,3,4,5,6,7,8,9]); opt.xtol_rel 1e-8; …

week07day01(powerbi)

一. Power BI简介 1. 构成部分 power query: 进行简单的数据清洗power pivot : 进行指标计算power view &#xff1a; 进行报表视图 二. Power Query (进行数据清洗) 1. 如何获取数据&#xff1a; 点击获取数据 ——> 选择导入数据的类型——> 会出现 "加载&…

Python学习:数据类型转换

数据类型转换 对数据内置的类型进行转换&#xff0c;数据类型的转换&#xff0c;一般情况下你只需要将数据类型作为函数名即可。 Python 数据类型转换可以分为两种&#xff1a; 隐式类型转换 - 自动完成显式类型转换 - 需要使用类型函数来转换 隐式类型转换 Python 会自动…

c/c++ | 求叶子结点个数 |构建B树 | 动态规划--找叶子结点个数

是这样的&#xff0c;一道代码题&#xff0c;根据输入数据&#xff0c;计算运行结果 #include<bits/stdc.h> using namespace std; vector<int>g[10]; int ans 0; void dfs(int x){if(g[x].size() 0){ans;return;}for(int i 0; i < g[x].size(); i){dfs(g[x]…

CVE-2019-5782:kArgumentsLengthType 设置偏小导致优化阶段可以错误的去除 CheckBound 节点

文章目录 环境搭建漏洞分析笔者初分析笔者再分析漏洞触发源码分析 漏洞利用总结 环境搭建 sudo apt install pythongit reset --hard b474b3102bd4a95eafcdb68e0e44656046132bc9 export DEPOT_TOOLS_UPDATE0 gclient sync -D// debug version tools/dev/v8gen.py x64.debug ni…

学会这几步,让酷开系统的使用体验更加出色!

在当今数字化快速发展的时代&#xff0c;用户体验&#xff08;User Experience, UX&#xff09;已成为产品和服务成功的关键因素之一。随着市场竞争的加剧&#xff0c;仅仅提供功能性强大的产品已不足以满足用户的需求&#xff0c;如何提升整体体验、确保用户的满意度和忠诚度&…

uniapp开发的跳转到小程序

uniapp开发的h5跳转到小程序 https://www.cnblogs.com/xiaojianwei/p/16352698.html官方&#xff1a;使用 URL Scheme 打开小程序 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/url-scheme.html 链接代码 <a href"weixin://dl/business/…

标准砂轮加工麻花钻或者铣刀螺旋槽齿形

螺旋槽与砂轮的空间位置运动关系可用下图表示&#xff0c;螺旋槽的形成靠工件绕轴线的旋转以及砂轮沿轴线的移动来完成的&#xff0c;以下坐标系可以清楚的描述二者之间的运动关系&#xff1a; 砂轮的形状如下&#xff1a; 经过坐标变换和下面这个重要的公式来计算工件的齿形…

【Docker】在 Ubuntu20.04 上配置 Docker 开发环境

【Docker】在 Ubuntu20.04 上配置 Docker 开发环境 1 安装 Docker2 加入 Docker 用户组 1 安装 Docker 参考文档: Link 卸载以避免冲突 for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done设…