JAVA:利用 Content Negotiation 实现多样式响应格式的技术指南
1、简述
Content Negotiation(内容协商) 是 RESTful 服务的重要特性,允许客户端和服务器根据请求的不同特性动态选择适合的响应格式。它是一种在 HTTP 协议中实现的机制,通过它,服务器能够根据客户端需求返回适合的内容类型(如 JSON、XML、HTML)。
本文将介绍 Content Negotiation 的原理、实现方式,并通过详细示例演示其在 Spring Boot 中的实际应用。

2、原理
Content Negotiation 的核心在于客户端通过 HTTP 请求头中的 Accept、Content-Type 等字段,告知服务器它支持的内容格式,而服务器根据这些信息返回匹配的内容。以下是主要的 HTTP 头字段:
- Accept:指定客户端希望接受的内容类型。例如:
Accept: application/json
表示客户端希望接收到 JSON 格式的响应。
-
Content-Type:指定请求体的内容格式(如 POST 请求的 JSON 数据)。
-
Accept-Language:指定客户端支持的语言。
Content Negotiation 有以下三种常见实现方式:
-
HTTP Header-Based Negotiation(基于请求头的协商)
客户端通过 Accept 头告知服务器期望的响应类型。
示例:Accept: application/xml。 -
URL Path-Based Negotiation(基于 URL 路径的协商)
通过扩展名直接指定期望的响应类型。
示例:/api/resource.json。 -
Query Parameter-Based Negotiation(基于查询参数的协商)
客户端通过查询参数指定期望的响应类型。
示例:/api/resource?format=json。
3、Content Negotiation 实现
Spring Boot 提供了对 Content Negotiation 的内置支持,可以轻松实现多种响应格式。
3.1 添加必要的依赖
确保你的项目中已经包含以下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>
</dependency>
3.2 配置 Content Negotiation
在 Spring Boot 中,通过 ContentNegotiationConfigurer 配置支持的内容协商方式:
package com.example.springbootclient.config;import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {configurer// 支持 URL 后缀形式,如 .json 或 .xml.favorPathExtension(true)// 支持查询参数,如 ?format=json 或 ?format=xml.favorParameter(true).parameterName("format")// 如果未指定,则根据请求头返回内容类型.ignoreAcceptHeader(false).useRegisteredExtensionsOnly(false)// 默认返回 JSON.defaultContentType(MediaType.APPLICATION_JSON)// 注册媒体类型.mediaType("json", MediaType.APPLICATION_JSON).mediaType("xml", MediaType.APPLICATION_XML);}
}
3.3 创建示例控制器
创建一个简单的 REST 控制器,用于返回多种格式的数据:
package com.example.springbootclient.controller;import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
@RequestMapping("/api")
public class ContentNegotiationController {@GetMapping(value = "/resource")public ResponseEntity<Object> getResource() {Map<String, String> data = new HashMap<>();data.put("id", "1");data.put("name", "Content Negotiation Example");return ResponseEntity.ok(data);}@GetMapping(value = "/resource.{format}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})public ResponseEntity<Object> getFormat() {Map<String, String> data = new HashMap<>();data.put("id", "1");data.put("name", "Content Negotiation Example");return ResponseEntity.ok(data);}
}
4、详细样例
以下是几种 Content Negotiation 的请求和响应示例:
4.1 基于 HTTP 请求头
请求:
GET /api/resource HTTP/1.1
Host: localhost:8080
Accept: application/json
响应:
{"id": "1","name": "Content Negotiation Example"
}
如果请求头为 Accept: application/xml,响应为:
<HashMap><name>Content Negotiation Example</name><id>1</id>
</HashMap>
4.2 基于 URL 路径扩展名
请求:
GET /api/resource.json HTTP/1.1
Host: localhost:8080
响应:
{"id": "1","name": "Content Negotiation Example"
}
请求:
GET /api/resource.xml HTTP/1.1
Host: localhost:8080
响应:
<HashMap><name>Content Negotiation Example</name><id>1</id>
</HashMap>
4.3 基于查询参数
请求:
GET /api/resource?format=json HTTP/1.1
Host: localhost:8080
响应:
{"id": "1","name": "Content Negotiation Example"
}
请求:
GET /api/resource?format=xml HTTP/1.1
Host: localhost:8080
响应:
<HashMap><name>Content Negotiation Example</name><id>1</id>
</HashMap>
5、Content Negotiation 的优缺点
5.1 优点:
- 客户端可以灵活选择所需的内容格式。
- 支持多种协商方式,适用性广。
- 降低了为不同格式创建独立 API 的复杂性。
5.2 缺点:
- 配置较为复杂,可能导致意外的行为。
- 扩展名协商可能不符合 RESTful API 的最佳实践。
- 对 Accept 头的支持可能不一致。
6、总结
Content Negotiation 是 RESTful API 中的重要功能,能够为客户端提供更好的灵活性。在 Spring Boot 中,Content Negotiation 的实现非常灵活,支持多种协商方式。通过合理的配置和设计,可以实现更加优雅和高效的服务接口。希望本文对你理解 Content Negotiation 的核心原理和实现有所帮助!
相关文章:
JAVA:利用 Content Negotiation 实现多样式响应格式的技术指南
1、简述 Content Negotiation(内容协商) 是 RESTful 服务的重要特性,允许客户端和服务器根据请求的不同特性动态选择适合的响应格式。它是一种在 HTTP 协议中实现的机制,通过它,服务器能够根据客户端需求返回适合的内…...
layui Table单元格编辑支持Enter键换行,包括下拉框单元格
layui Table表格编辑支持Enter键换行 可编辑单元格 $(".layui-table td").keydown(function (e) {// console.log("111",e);var index $(this).index(),tr $(this).parent(tr),isKeydown (event.type "keydown");if (e.code "Enter&q…...
Swoole的MySQL连接池实现
在Swoole中实现MySQL连接池可以提高数据库连接的复用率,减少频繁创建和销毁连接所带来的开销。以下是一个简单的Swoole MySQL连接池的实现示例: 首先,确保你已经安装了Swoole扩展和PDO_MySQL扩展(或mysqli,但在这个示…...
无人机红外热成像:应急消防的“透视眼”
无人机红外热成像:应急消防的“透视眼” 亲爱的小伙伴们,每年一到夏天,应急消防的战士们就像上紧了发条的闹钟,时刻准备应对各种灾害。炎热天气让火灾隐患“蹭蹭”往上涨,南北各地还有防洪救灾、台风、泥石流等灾害轮…...
【redis】Redis操作String类型key的发生了什么?
关于Redis操作(添加、删除、修改、查询)String类型key的完整过程,包括引用源码数据、时序图、磁盘IO读写、数据长度限制和故障处理机制。 数据结构 Redis对象(robj) typedef struct redisObject {unsigned type:4; …...
hdfs之读写流程
写入流程: 客户端Client想将文件a.txt上传至hdfs,首先向Namenode发送请求进行权限校验,Namenode通过后会计算出来三个节点,并将这三个节点告知客户端,客户端将输入进行切割成块,一个一个的块进行传输&…...
研发的立足之本到底是啥?
0 你的问题,我知道! 本文深入T型图“竖线”的立足之本:专业技术 技术赋能业务能力。研发在学习投入精力最多,也误区最多。 某粉丝感发展遇到瓶颈,项目都会做,但觉无提升,想跳槽。于是&#x…...
Baklib揭示内容中台与人工智能技术的创新协同效应
内容概要 在当今信息爆炸的时代,内容的高效生产与分发已成为各行业竞争的关键。内容中台与人工智能技术的结合,为企业提供了一种新颖的解决方案,使得内容创造的流程更加智能化和高效化。 内容中台作为信息流动的核心,能够集中管…...
智慧消防营区一体化安全管控 2024 年度深度剖析与展望
在 2024 年,智慧消防营区一体化安全管控领域取得了令人瞩目的进展,成为保障营区安全稳定运行的关键力量。这一年,行业在政策驱动、技术创新应用、实践成果及合作交流等方面呈现出多元且深刻的发展态势,同时也面临着一系列亟待解决…...
自定义数据集,使用 PyTorch 框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测
在本文中,我们将展示如何使用 NumPy 创建自定义数据集,利用 PyTorch 实现一个简单的逻辑回归模型,并在训练完成后保存该模型,最后加载模型并用它进行预测。 1. 创建自定义数据集 首先,我们使用 NumPy 创建一个简单的…...
UE5 特效
能帮到你的话,就给个赞吧 😘 文章目录 post processexposurebloomvignettesaturationunbound material材质蓝图alt z base colorconstant3Vector roughnessconstant metallicconstant pbrroughnessmetallicmake more realmake some areas rougher than o…...
CMAKE工程编译好后自动把可执行文件传输到远程开发板
# 设置 CMake 最低版本要求 cmake_minimum_required(VERSION 3.10)# 设置项目名称 project(MyProject)# 添加可执行文件,这里以项目名作为可执行文件的名称 add_executable(${PROJECT_NAME} main.cpp)# 设置开发板信息 set(DEVELOPMENT_BOARD_IP "192.168.1.10…...
Windows 程序设计7:文件的创建、打开与关闭
文章目录 前言一、文件的创建与打开CreateFile1. 创建新的空白文件2. 打开已存在文件3. 打开一个文件时,如果文件存在则打开,如果文件不存在则新创建文件4.打开一个文件,如果文件存在则打开文件并清空内容,文件不存在则 新创建文件…...
策略模式 - 策略模式的使用
引言 在软件开发中,设计模式是解决常见问题的经典解决方案。策略模式(Strategy Pattern)是行为型设计模式之一,它允许在运行时选择算法的行为。通过将算法封装在独立的类中,策略模式使得算法可以独立于使用它的客户端…...
具身智能研究报告
参考: (1)GTC大会&Figure:“具身智能”奇点已至 (2)2024中国具身智能创投报告 (3)2024年具身智能产业发展研究报告 (4)具身智能行业深度:发展…...
Windows安装Milvus
安装Milvus 安装Docker前置条件: 安装Mlivus方案一方案二 Attu管理端 安装Docker 系统:Windows 11 家庭中文版 Mlivus:V2.3.0 Attu: V2.3.10 前置条件: 启用“适用于 Linux 的 Windows 子系统”可选功能,才能在 Win…...
Excel分区间统计分析(等步长、不等步长、多维度)
在数据分析过程中,可能会需要统计不同数据区间的人数、某个数据区间的平均值或者进行分组区间统计,本文从excel函数到数据透视表的方法,从简单需求到复杂需求,采用不同的方法进行讲解,尤其是通过数据透视表的强大功能大…...
宝塔mysql数据库容量限制_宝塔数据库mysql-bin.000001占用磁盘空间过大
磁盘空间占用过多,排查后发现网站/www/wwwroot只占用7G,/www/server占用却高达8G,再深入排查发现/www/server/data目录下的mysql-bin.000001和mysql-bin.000002两个日志文件占去了1.5G空间。 百度后学到以下知识,做个记录。 mysql…...
LeetCode 2412.完成所有交易的初始最少钱数:【年度巨献】举例说明(讲明白),由难至简(手脚不乱),附Python一行版
【LetMeFly】2412.完成所有交易的初始最少钱数:【年度巨献】举例说明(讲明白),由难至简(手脚不乱),附Python一行版 文章目录 【LetMeFly】2412.完成所有交易的初始最少钱数:【年度巨献】举例说明(讲明白),由难至简(手脚…...
多人-多agent协同可能会挑战维纳的反馈
在多人-多Agent协同系统中,维纳的经典反馈机制将面临新的挑战,而协同过程中的“算计”(策略性决策与协调)成为实现高效协作的核心。 1、非线性与动态性 维纳的反馈理论(尤其是在控制理论中)通常假设系统的动…...
自动驾驶运动规划:MPC算法实现与“反重力”平滑控制实践
1. 项目概述:当自动驾驶遇见“反重力”最近在GitHub上闲逛,发现一个名字特别酷的项目——aryanbisht555/antigravity-autopilot。第一眼看到这个名字,我脑子里立刻蹦出两个词:“反重力”和“自动驾驶”。这组合听起来像是科幻电影…...
ARM Cortex-M处理器仿真与Iris组件深度解析
1. ARM Cortex-M系列处理器仿真技术概述在嵌入式系统开发领域,处理器仿真技术已经成为不可或缺的工具链环节。作为ARM架构中专门面向微控制器市场的产品线,Cortex-M系列处理器凭借其优异的能效比和实时性能,广泛应用于物联网终端、工业控制和…...
合肥工业大学LaTeX论文模板:5分钟解决格式难题的专业方案
合肥工业大学LaTeX论文模板:5分钟解决格式难题的专业方案 【免费下载链接】HFUT_Thesis LaTeX Thesis Template for Hefei University of Technology 项目地址: https://gitcode.com/gh_mirrors/hf/HFUT_Thesis 还在为论文格式调整而烦恼吗?合肥工…...
Docker Compose实战:一键部署OpenClaw项目与环境管理
1. 项目概述:一个为OpenClaw项目量身定制的Docker助手 如果你正在折腾一个名为OpenClaw的开源项目,并且被它复杂的依赖环境、繁琐的配置步骤搞得焦头烂额,那么你很可能需要“vivganes/openclaw-docker-helper”这个工具。简单来说࿰…...
普通人 0 基础能转网安吗?转行路径全面拆解,告诉你到底值不值得
前言 最近在后台有看到很多朋友问我关于网络安全转行的问题,今天做了一些总结,其中最多的是,觉得目前的工作活多钱少、不稳定、一眼望到头,还有一些就是目前工作稳定但是缺乏上升空间的。总的来说,大家主要的问题是&a…...
Agent监控管理工具agenttop:实现自动化任务的可观测性与可控性
1. 项目概述与核心价值最近在开源社区里,我注意到一个名为vicarious11/agenttop的项目开始受到一些开发者的关注。乍一看这个标题,你可能会和我最初的反应一样:这又是一个“Agent”相关的工具,现在这类项目多如牛毛。但当我花时间…...
从MC1496乘法器到DSB调制:一个经典电路的设计实践与参数解析
1. DSB调制基础与MC1496乘法器简介 第一次接触DSB调制电路时,我被那个看似简单的波形变换背后精妙的数学原理深深吸引。DSB(Double Sideband)双边带调制,本质上是用低频信号去控制高频载波的幅度,但与传统AM调制不同&a…...
联盟营销管理系统有哪些?如何选择?
在SaaS工具出海营销的广阔天地里,联盟营销(Affiliate Marketing)以其独特的优势成为众多企业竞相探索的流量获取新途径。本文将简要介绍几款主流的联盟营销工具,探讨其独特之处及适用场景。PartnerShare联盟系统PartnerShare联盟系统是中国出…...
OBS多路RTMP推流插件:一站式解决多平台同步直播难题
OBS多路RTMP推流插件:一站式解决多平台同步直播难题 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 还在为每次直播需要在不同平台间手动切换而烦恼吗?obs-multi…...
3步轻松解锁Cursor Pro完整功能:免费使用AI编程助手的终极指南
3步轻松解锁Cursor Pro完整功能:免费使用AI编程助手的终极指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached …...
