内容协商源码解析与自定义 MessageConverter

目录

内容协商

1、引入xml依赖

2、postman分别测试返回json和xml

 3、开启浏览器参数方式内容协商功能

4、内容协商原理

5、自定义 MessageConverter

综上


内容协商

根据客户端接收能力不同,返回不同媒体类型的数据。

若客户端无法解析服务端返回的内容,即媒体类型未匹配,那么相应406。

1、引入xml依赖

默认没有返回xml的能力 

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

2、postman分别测试返回json和xml

只需要改变请求头中Accept字段。(Http协议中规定的,告诉服务器,该客户端可以接收的数据类型。)

 3、开启浏览器参数方式内容协商功能

spring:mvc:contentnegotiation:# 开启请求参数内容协商模式favor-parameter: true# 修改parameterName,默认为formatparameter-name: xx

发请求格式:

http://localhost:8080/test/person?format=json

http://localhost:8080/test/person?format=xml

注意:1.如果没有定义参数名字,默认parameterName为format。

           2.引入jackson转换xml包后,则支持json、xml两种媒体类型。(如果需要其他类型数据,可自定义MessageConverter,实现多协议数据兼容)

浏览器端不传参数或者是没匹配到,就是"*/*",都能匹配,然后按权重匹配。

4、内容协商原理

内容协商的内容在返回值处理器 RequestResponseBodyMethodProcessor->writeWithMessageConverters() 方法中

  • 1、判断当前响应头中是否已经保存了 MediaType,如果有则该 MediaType 作为 selectedMediaType。

  • 2、否则,先获取浏览器可接受的所有MediaType: acceptableType

获取的原理:调用返回值处理器的内容协商管理器来获取到当前请求头中 Accept 字段的值,封装到 List 中,并按权重进行排序。

  • 3、获取支持当前返回值类型的 MessageConverter 所支持的所有 MediaType:producibleTypes

获取的原理:获取当前处理器中保存的所有 MessageConverter,匹配支持当前返回值类型的 MessageConverter,将这些 MessageConverter 支持的所有 MediaType 返回。

  • 4、对两种类型进行最佳匹配,筛选出所有可以使用的 MediaType:mediaTypesToUse

对 mediaTypesToUse 按权重进行排序,优先选中优先级较高的作为选定的 MediaType:selectedMediaType。如果匹配到不是具体的 MediaType(带通配符 *),则 selctedMediaType = application/octet-stream。

 

  • 5、遍历循环所有当前系统的 MessageConverter,匹配支持将当前返回值类型 转换为 selectedMediaType 的 MessageConverter,并使用其 write() 方法将当前返回值写入到响应体中。

5、自定义 MessageConverter

实现多协议数据兼容。json、xml、xx-media。

如何新增一个自定义的xx-media格式?

使用spring boot可以基于配置文件快速修改媒体类型。

spring:mvc:contentnegotiation:# 开启请求参数内容协商模式favor-parameter: true# 修改parameterName,默认为formatparameter-name: xx# 自定义媒体类型media-types:xx-media: application/xx-media

 或者如果不修改xml文件,还可以通过重写configureContentNegotiation方法来实现

@Configuration
public class WebConfig {@Beanpublic WebMvcConfigurer webMvcConfigurer () {return new WebMvcConfigurer() {@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {configurer.mediaType("xx-media", MediaType.parseMediaType("application/xx-media"));}@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new CustomConverter());}};}
}

 配置完,可以看到客户端、浏览器可接收的媒体类型如下:

 

无论使用xml形式,还是重写configureContentNegotiation都需要写一个自定义converter。

举个例子,只处理写数据。

public class CustomConverter implements HttpMessageConverter<User> {@Overridepublic boolean canRead(Class clazz, MediaType mediaType) {return false;}@Overridepublic boolean canWrite(Class clazz, MediaType mediaType) {return clazz.isAssignableFrom(User.class);}@Overridepublic List<MediaType> getSupportedMediaTypes() {return MediaType.parseMediaTypes("application/xx-media");}@Overridepublic User read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {return null;}@Overridepublic void write(User user, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {// 自定义协议数据写出String data = user.getName() + "---" +user.getSex() + "---" + user.getAge();//写出去OutputStream body = outputMessage.getBody();body.write(data.getBytes());}
}

 请求结果显示如下:

综上

无论使用浏览器参数访问形式,还是通过postman修改请求头的accept接收值,都可以支持application/xml、application/json、application/xx-media类型的数据。

 ​​​​​​       

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vatee万腾平台:创新科技,驱动未来

在科技日新月异的今天&#xff0c;每一个创新的火花都可能成为推动社会进步的重要力量。Vatee万腾平台&#xff0c;作为科技创新领域的佼佼者&#xff0c;正以其卓越的技术实力、前瞻性的战略眼光和不懈的探索精神&#xff0c;驱动着未来的车轮滚滚向前。 Vatee万腾平台深知&am…

剖析自闭症孩子玩手的独特之处

自闭症孩子玩手的行为常常具有一些较为独特的特点。 重复性是一个显著的特征。他们可能会以一种几乎相同的方式、节奏和频率反复地摆弄自己的手&#xff0c;例如不停地握拳、张开&#xff0c;或者持续地旋转手腕。 动作的单调性也是常见的。玩手的方式可能较为单一&#xff0c;…

【正点原子i.MX93开发板试用连载体验】简单的音频分类

本文最早发表于电子发烧友论坛&#xff1a; 今天测试的内容是进行简单的音频分类。我们要想进行语音控制&#xff0c;就需要构建和训练一个基本的自动语音识别 (ASR) 模型来识别不同的单词。如果想了解这方面的知识可以参考TensorFlow的官方文档&#xff1a;简单的音频识别&…

矢量绘图设计Sketch中文 Sketch直装安装包

Sketch是一款专为UI设计师和UX专家打造的矢量图形设计软件&#xff0c;以其简洁的界面、强大的功能和高效的协作能力而闻名。Sketch支持快速创建高质量的UI界面、图标、图形和插画&#xff0c;其矢量绘图工具让设计细节更加精准。同时&#xff0c;Sketch内置丰富的插件和组件库…

1-认识网络爬虫

1.什么是网络爬虫 ​ 网络爬虫&#xff08;Web Crawler&#xff09;又称网络蜘蛛、网络机器人&#xff0c;它是一种按照一定规则&#xff0c;自动浏览万维网的程序或脚本。通俗地讲&#xff0c;网络爬虫就是一个模拟真人浏览万维网行为的程序&#xff0c;这个程序可以代替真人…

【xinference】(15):在compshare上,使用docker-compose运行xinference和chatgpt-web项目,配置成功!!!

视频演示 【xinference】&#xff08;15&#xff09;&#xff1a;在compshare上&#xff0c;使用docker-compose运行xinference和chatgpt-web项目&#xff0c;配置成功&#xff01;&#xff01;&#xff01; 1&#xff0c;安装docker方法&#xff1a; #!/bin/shdistribution$(…

深入了解代理IP常见协议:区别与选择

代理服务器在网络使用中扮演着重要的角色&#xff0c;是您设备和互联网之间的中间层。它不仅可以增强网络访问的安全性和隐私保护&#xff0c;还可以提供许多灵活的应用。使用代理时&#xff0c;不同的协议类型对数据交换具有不同的规则和特征。常见的代理协议包括HTTP代理、HT…

通过Umijs从0到1搭建一个React项目

有一阵时间没写react了&#xff0c;今天通过umi搭建一个demo项目复习一下react&#xff1b;umi是一个可扩展的企业级前端应用框架&#xff0c;在react市场中还是比较火的一个框架。 Umi官方文档&#xff1a;Umi 介绍 (umijs.org) 一、构建项目。 1、安装包管理工具。 官方推…

七人共赢拼团模式的深度剖析与互助精神重塑

在当今电商的浩瀚星海中&#xff0c;七人共赢拼团模式以其创新的合作框架与激励体系&#xff0c;正引领着消费与商业的新潮流。这一模式不仅优化了购物体验&#xff0c;更深刻诠释了互助共赢的核心理念。以下&#xff0c;我们将从直推奖励、自动补齐机制及团队荣耀奖三个方面&a…

LLM应用:行业大模型

大语言模型正在朝着两个方向发展&#xff0c;一个是以ChatGPT为代表的通用大模型&#xff0c;另一个则是行业大模型&#xff08;或称为“专业大模型”&#xff09;。如果大模型的演化分为阴阳两面&#xff0c;通用大模型更像是阳面&#xff0c;受众更广、更to C端&#xff0c;以…

动手学深度学习(Pytorch版)代码实践 -循环神经网络-57长短期记忆网络(LSTM)

57长短期记忆网络&#xff08;LSTM&#xff09; 1.LSTM原理 LSTM是专为解决标准RNN的长时依赖问题而设计的。标准RNN在训练过程中&#xff0c;随着时间步的增加&#xff0c;梯度可能会消失或爆炸&#xff0c;导致模型难以学习和记忆长时间间隔的信息。LSTM通过引入一组称为门…

大型企业如何整合集成全域数据、解决数据孤岛难题?

今天&#xff0c;我们说一下大型企业全域数据的整合集成问题。 通常&#xff0c;中大型企业和集团公司拥有大量多源异构的数据存储资源&#xff0c;如数据仓库、数据湖以及分布于分子公司和混合多云平台的业务系统&#xff0c;通过传统物理集中统一数据资产管理的方式难度高&a…

Springboot 设置个性化banner

在 Spring Boot 中自定义 banner 的方法有几种&#xff0c;可以通过以下步骤来实现&#xff1a; 1、使用文本文件作为 banner 在 src/main/resources 目录下创建一个名为 banner.txt 的文件。 编辑这个文件&#xff0c;输入想要显示的文本。确保文本中包含换行符和空格…

Android OpenGL ES 离屏幕渲染1——EGL环境的创建,以及基础概念的理解

创建EGL上下文、配置EGL环境、创建EGL DISPLAY 什么是EGL&#xff1a; 由于OpenGL ES并不负责窗口管理以及上下文管理&#xff0c;该职责由各个平台自行完成&#xff1b;在Android平台下OpenGL ES的上下文环境是依赖EGL的API进行搭建的。 对于EGL这个框架&#xff0c;谷歌已经提…

MES系统在工业4.0时代的应用与前景

在工业4.0时代&#xff0c;制造执行系统&#xff08;MES&#xff09;在现代制造业中的作用变得愈发重要。一个优秀的MES系统不仅可以提高生产效率和质量控制&#xff0c;还可以帮助企业实现智能制造&#xff0c;提升市场竞争力。 一、MES系统的基本概念与功能 制造执行系统&a…

补码一位乘法原理(布斯编码详讲)

最近在看补码乘法的时候&#xff0c;感觉到很奇怪的一点&#xff0c;那就是补码的一位乘法&#xff0c;就是上网查了大量的资料都没有理解到它真正的原理&#xff0c;总感觉还是不会。那么&#xff0c;补码乘法的原理到底是什么呢&#xff1f;而让我们一直困惑的点是哪里呢&…

宿州降本 提质 增效 数据采集监控平台提高生产自动化水平

在当今竞争激烈的市场环境中&#xff0c;企业追求降本、提质、增效已成为发展的关键。而我们的[数据采集监控平台名称]数据采集监控平台&#xff0c;正是助力企业实现这一目标的强大工具。 LP-SCADA数据采集监控平台是工业4.0中主要的数据采集系统之一&#xff0c;主要针对产线…

nginx的知识面试易考点

Nginx概念 Nginx 是一个高性能的 HTTP 和反向代理服务。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力在同类型的网页服务器中表现较好。 Nginx 专为性能优化而开发&#xff0c;性能是其最重要的考量指标&#xff0c;实现上非常注重效率&#…

for nested data item, row-key is required.报错解决

今天差点被一个不起眼的bug搞到吐&#xff0c;就是在给表格设置row-key的时候&#xff0c;一直设置不成功&#xff0c;一直报错缺少row-key&#xff0c;一共就那两行代码 实在是找不到还存在什么问题... 先看下报错截图... 看下代码 我在展开行里面用到了一个表格 并且存放表格…

Python数据分析案例50——基于EEMD-LSTM的石油价格预测

案例背景 很久没更新时间序列预测有关的东西了。 之前写了很多CNN-LSTM&#xff0c;GRU-attention&#xff0c;这种神经网络之内的不同模型的缝合&#xff0c;现在写一个模态分解算法和神经网络的缝合。 虽然eemd-lstm已经在学术界被做烂了&#xff0c;但是还是很多新手小白或…