当前位置: 首页 > article >正文

学透Spring Boot — 017. 魔术师—Http消息转换器

本文是我的专栏《学透Spring Boot》的第17篇文章,了解更多请移步我的专栏:

学透 Spring Boot_postnull咖啡的博客-CSDN博客

目录

HTTP请求和响应

需求—新的Media Type

实现—新的Media Type

定义转换器

注册转换器

编写Controller

测试新的mediatype

Http消息转换器实现原理

总结


HTTP请求和响应

很多接口,我们发起HTTP请求,请求参数是json。得到的响应也是json。

但是我们的控制器中,是使用Java对象来接收请求,出参也是Java对象。

而不是JSONObject。

这样的好处是更好操作,不用再次把Json对象转换成Java对象。

这是怎么做到的呢?

是不是和上一篇的Spring MVC Conversion Service 类型转换 一样的原理呢?

是,但不完全是。

需求—新的Media Type

先来实现一个需求,看看能不能实现。

我们希望我们的请求是这样

和普通的请求不太一样,主要有亮点:

  1. 我们的MediaType是自己定义“hehe/nba”
  2. 我们的数据体是自己构造的文本,用###分割字段

一般情况,没人会自定定义媒体类型,用得最多的是xml和json。

我们这里这么做,是为了理解json消息体是怎么解析的。

实现—新的Media Type

定义转换器

首先我们先定义一个新Http消息转换器。

它继承的是HttpMessageConverter接口。

注意这里实现的是HttpMessageConverter接口,和我们上一篇文章的类型转换器不一样,它实现的是Converter接口。

public class CarHttpConverter implements HttpMessageConverter<Car> {private static final String SPLITCHAR = "###";private static final String MY_MEDIA_TYPE1 = "hehe/nba;charset=UTF-8";private static final String MY_MEDIA_TYPE2 = "hehe/nba";@Overridepublic boolean canRead(Class<?> clazz, MediaType mediaType) {if(mediaType == null){return true;}return clazz == Car.class&& (mediaType.equals(MediaType.valueOf(MY_MEDIA_TYPE1)) || mediaType.equals(MediaType.valueOf(MY_MEDIA_TYPE2)));}@Overridepublic boolean canWrite(Class<?> clazz, MediaType mediaType) {if(mediaType == null){return true;}return clazz == Car.class&& (mediaType.equals(MediaType.valueOf(MY_MEDIA_TYPE1)) || mediaType.equals(MediaType.valueOf(MY_MEDIA_TYPE2)));}@Overridepublic List<MediaType> getSupportedMediaTypes() {return List.of(MediaType.valueOf(MY_MEDIA_TYPE1), MediaType.valueOf(MY_MEDIA_TYPE2));}@Overridepublic Car read(Class<? extends Car> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {// 从输入流中读取 CSV 数据并将其转换为 Book 对象InputStreamReader reader = new InputStreamReader(inputMessage.getBody());StringBuilder csvData = new StringBuilder();int character;while ((character = reader.read()) != -1) {csvData.append((char) character);}String[] fields = csvData.toString().split(SPLITCHAR);String type = fields[0];double price = Double.parseDouble(fields[1]);String year = fields[2];return Car.builder().type(type).price(price).year(year).build();}@Overridepublic void write(Car car, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {OutputStreamWriter writer = new OutputStreamWriter(outputMessage.getBody());String csvData = car.getType() + SPLITCHAR + car.getPrice() + SPLITCHAR + car.getYear();writer.write(csvData);writer.flush();}
}

注册转换器

然后,注册这个Http消息转换器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new CarHttpConverter());}
}

编写Controller

特别注意,我们这里的consum和produce用的media type是我们自定义的type。

consumes 指定接收HTTP请求的mediaytpe

produces 指定发送HTTP响应的mediatype

@RestController
@Log
public class HttpMsgController {@PostMapping(path = "/buyCar", consumes = "hehe/nba", produces = "hehe/nba")public Car buyCar(@RequestBody Car car){car.setYear("2025");return car;}
}

测试新的mediatype

设置content type。hehe/nba是我们自定义的type。

设置request body,我们的内容是用###做分隔符的。

这是我们约定的格式。

大功告成!

我们没有使用json,但是定了一个一种新的序列化格式!!!hehe/nba!

Http消息转换器实现原理

我们可以debug看看消息转换器注册的代码。

converters列表中包含了我们新定义的转换器,还包括了Jackson的消息转换器。

我们再看看Spring Boot是如何自动配置Jackson的。

找到Spring Boot的配置类列表

怎么定位这个文件,请参考我之前的文章。

列表中包含了Spring MVC的自动配置WebMvcAutoConfiguration

大部分的默认配置在WebMvcConfigurationSupport。

可以看到,当我们的classpath下,有jackson的包,就会自动使用Jackson处理requestbody和response body.

总结

本文我们定义了一个新的content type, 构造新的请求体和响应体。希望通过本文,你对Http 消息转换器有更多的了解。

相关文章:

学透Spring Boot — 017. 魔术师—Http消息转换器

本文是我的专栏《学透Spring Boot》的第17篇文章&#xff0c;了解更多请移步我的专栏&#xff1a; 学透 Spring Boot_postnull咖啡的博客-CSDN博客 目录 HTTP请求和响应 需求—新的Media Type 实现—新的Media Type 定义转换器 注册转换器 编写Controller 测试新的medi…...

BOE(京东方)旗下控股子公司“京东方能源”成功挂牌新三板 以科技赋能零碳未来

2025年4月8日,BOE(京东方)旗下控股子公司京东方能源科技股份有限公司(以下简称“京东方能源”)正式通过全国中小企业股份转让系统审核,成功在新三板挂牌(证券简称:能源科技,证券代码:874526),成为BOE(京东方)自物联网转型以来首个独立孵化并成功挂牌的子公司。此次挂牌是BOE(京…...

Airflow集成Lark机器人

🥭1. 实现目标 🕐 通过自定义函数,实现Lark机器人告警功能 🕐 通过Lark机器人代替邮件数据的发送功能 🥭2.自定义函数实现 from airflow import DAG from airflow.operators.python_operator import PythonOperator from airflow.models import Variable import requ…...

Git使用与管理

一.基本操作 1.创建本地仓库 在对应文件目录下进行&#xff1a; git init 输入完上面的代码&#xff0c;所在文件目录下就会多一个名为 .git 的隐藏文件&#xff0c;该文件是Git用来跟踪和管理仓库的。 我们可以使用 tree 命令&#xff08;注意要先下载tree插件&#xff09…...

计算机网络——传输层(Udp)

udp UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议 &#xff09;是一种无连接的传输层协议&#xff0c;它在IP协议&#xff08;互联网协议&#xff09;之上工作&#xff0c;为应用程序提供了一种发送和接收数据报的基本方式。以下是UDP原理的详细解释&…...

网络安全小知识课堂(五)

病毒与蠕虫&#xff1a;你的电脑为何会 “生病” 和 “传染”&#xff1f; 引言 你是否见过这样的场景&#xff1a;电脑突然弹窗广告暴增&#xff0c;文件莫名消失&#xff0c;甚至整个公司网络集体瘫痪&#xff1f;这些症状背后&#xff0c;可能是 ** 病毒&#xff08;Virus…...

图解Java设计模式

1、设计模式面试题 2、设计模式的重要性 3、7大设计原则介绍 3.1、单一职责原则...

wsl2+ubuntu22.04安装blender教程(详细教程)

本章教程介绍,如何在Windows操作系统上通过wsl2+ubuntu安装blender并运行教程。Blender 是一款免费、开源的 ​​3D 创作套件​​,广泛应用于建模、动画、渲染、视频编辑、特效制作等领域。它由全球开发者社区共同维护,支持跨平台(Windows、macOS、Linux),功能强大且完全…...

其他合成方式介绍

在 SurfaceFlinger 的 Layer 处理逻辑中&#xff0c;除了常见的 Client Composition&#xff08;GPU合成&#xff09; 和 Device Composition&#xff08;HWC合成&#xff09;&#xff0c;还存在一些特殊的合成方式&#xff0c;比如 Sideband、Solid Color 和 Display Decorati…...

Spring AI Alibaba MCP 市场正式上线!

Spring AI Alibaba 正式上线 MCP 市场&#xff1a;Spring AI Alibaba-阿里云Spring AI Alibaba官网官网。 开发者可以在这里搜索市面上可用的 MCP Server 服务&#xff0c;了解每个服务的实现与接入方法。 MCP 市场是做什么的&#xff1f; Spring AI Alibaba MCP 当前主要提供…...

Spring Security基本入门

1、为什么要使用权限框架 权限管理是所有后台系统的都会涉及的一个重要组成部分&#xff0c;主要目的是对不同的人访问资源进行权限的控制&#xff0c;避免因权限控制缺失或操作不当引发的风险问题&#xff0c;如操作错误&#xff0c;隐私数据泄露等问题。 2、权限管理的常见…...

【Hadoop入门】Hadoop生态圈概述:核心组件与应用场景概述

1 Hadoop生态圈概述 Hadoop生态圈是以 HDFS&#xff08;分布式存储&#xff09; 和 YARN&#xff08;资源调度&#xff09; 为核心&#xff0c;围绕大数据存储、计算、管理、分析等需求发展出的一系列开源工具集合。 核心特点&#xff1a; 模块化&#xff1a;各组件专注解决特定…...

深入理解 Spring 的 MethodParameter 类

MethodParameter 是 Spring 框架中一个非常重要的类&#xff0c;它封装了方法参数&#xff08;或返回类型&#xff09;的元数据信息。这个类在 Spring MVC、AOP、数据绑定等多个模块中都有广泛应用。 核心功能 MethodParameter 主要提供以下功能&#xff1a; 获取参数类型信息…...

人工智能:GPT技术应用与未来展望

GPT(Generative Pre-trained Transformer)作为自然语言处理领域的代表性技术,近年来在各行业的实际应用中展现出广泛潜力。结合其技术特性与行业需求,以下是GPT的主要应用场景、案例分析及未来挑战的总结: 一、核心应用领域与案例 文本生成与内容创作 自动化内容生产:GPT…...

解决编译内核报错:No rule to make target ‘debian/canonical-certs.pem‘

解决编译内核报错&#xff1a;No rule to make target ‘debian/canonical-certs.pem‘问题 更换内核后重新编译内核报错1如下&#xff1a; make[1]: *** No rule to make target debian/canonical-certs.pem, needed by certs/x509_certificate_list. Stop. make: *** [Mak…...

spring mvc中不同服务调用类型(声明式(Feign)、基于模板(RestTemplate)、基于 SDK、消息队列、gRPC)对比详解

RestControllerAdvice 和 ControllerAdvice 对比详解 1. 基本概念 注解等效组合核心作用ControllerAdviceComponent RequestMapping&#xff08;隐式&#xff09;定义全局控制器增强类&#xff0c;处理跨控制器的异常、数据绑定或全局响应逻辑。RestControllerAdviceControll…...

【Java设计模式】第1章 课程导学

第1章 课程导学 1-1 课堂导学 课程介绍 设计模式是工程师必备知识&#xff0c;面试高频考点。课程目标&#xff1a;提炼常用设计模式精华&#xff0c;结合场景演进和源码解析&#xff0c;系统学习设计模式。课程特色&#xff1a; 动态递进式讲解&#xff0c;通过场景变化展示…...

Java + WebAssembly 2025:如何用Rust优化高性能Web应用?

&#x1f4dd; 摘要 随着WebAssembly(WASM)技术的成熟&#xff0c;Java开发者现在可以通过结合Rust来构建更高性能的Web应用。本文将详细介绍如何在2025年的技术栈中使用Java和Rust通过WebAssembly实现性能优化&#xff0c;包括基础概念、实际应用场景、详细代码示例以及性能对…...

MCU控制4G模组(标准AT命令),CatM的最大速率?

根据3GPP标准&#xff0c;Cat M1的上行峰值速率大约是1 Mbps&#xff0c;下行大约是1 Mbps。但实际速率会受到多种因素影响&#xff0c;比如网络条件、信号强度、模块配置等。 考虑使用AT命令时的开销。每次发送数据都需要通过AT命令&#xff0c;比如ATQISEND&#xff0c;会引…...

致远OA —— 表单数据获取(前端)

文章目录 :apple: 业务需求描述 &#x1f34e; 业务需求描述 测试案例&#xff1a; https://pan.quark.cn/s/3f58972f0a27 官网地址&#xff1a; https://open.seeyoncloud.com/v5devCAP/94/355/359/399/405/406.html 需求描述&#xff1a; 点击获取数据接口&#xff0c;…...

游戏引擎学习第214天

总结并为当天的任务做好准备 昨天&#xff0c;我们将所有调试控制代码迁移到使用新的调试接口中&#xff0c;但我们没有机会实际启用这些代码。我们做了很多准备工作&#xff0c;比如规划、将其做成宏、并将其放入调试流中&#xff0c;但实际上我们还没有办法进行测试。 今天…...

码率自适应(ABR)相关论文阅读简报2

论文5简介 标题&#xff1a;PAR:IMPROVING VIDEO BITRATE ADAPTATION VIA PAYLOAD-A W ARE THROUGHPUT PREDICTION 作者&#xff1a;Jialiang Pei, Congkai An, Anfu Zhou, Liang Liu, Huadong Ma 单位: 中国北京邮电大学计算机学院 发表会议&#xff1a; Conference on Mu…...

环信鸿蒙版 UIKit 快速上手指南

环信鸿蒙版 UIKit 是专为 HarmonyOS 开发者设计的 IM UI 组件库&#xff0c;基于环信 IM SDK 开发&#xff0c;可帮助开发者快速集成即时通讯功能。 环信UIKit 的特点 ArkUI 声明式开发范式&#xff1a;采用高效简洁的声明式开发方式状态管理 V2&#xff1a;支持深度观测和精…...

核心机制与主流协议解析

一、收益聚合器的核心逻辑 收益聚合器&#xff08;Yield Aggregator&#xff09;通过算法自动优化用户在DeFi协议中的资金配置&#xff0c;解决「收益耕作&#xff08;Yield Farming&#xff09;」的两大痛点&#xff1a; 机会捕捉&#xff1a;实时追踪高收益矿池&#xff08…...

使用stm32cubeide stm32f407 lan8720a freertos lwip 实现udp client网络数据转串口数据过程详解

1前言 项目需要使用MCU实现网络功能&#xff0c;后续确定方案stm32f407 外接lan8720a实现硬件平台搭建&#xff0c;针对lan8720a也是用的比较多的phy&#xff0c;网上比较多的开发板&#xff0c;硬件上都是选用了这个phy&#xff0c;项目周期比较短&#xff0c;选用了这个常用…...

Go:入门

文章目录 Hello, World命令行参数找出重复行GIF动画获取一个URL并发获取多个URL一个 Web 服务器其他 Hello, World Hello world package main import "fmt" func main() {fmt.Println("Hello, 世界") }package main表明这是一个可独立执行的程序包&#…...

createContext+useContext+useReducer组合管理React复杂状态

createContext、useContext 和 useReducer 的组合是 React 中管理全局状态的一种常见模式。这种模式非常适合在不引入第三方状态管理库&#xff08;如 Redux&#xff09;的情况下&#xff0c;管理复杂的全局状态。 以下是一个经典的例子&#xff0c;展示如何使用 createContex…...

JVM常见问题与调优

目录 一、内存管理问题 1、内存泄漏&#xff08;Memory Leak&#xff09; 2、内存溢出&#xff08;OOM, OutOfMemoryError&#xff09; 2.1 堆内存溢出&#xff08;OutOfMemoryError: Java heap space&#xff09; 2.2 元空间溢出&#xff08;OutOfMemoryError: Metaspace…...

汽车售后诊断 ODX 和 OTX 对比分析报告

一、引言 在汽车行业不断发展的当下&#xff0c;汽车售后诊断技术对于保障车辆性能、维护车主权益以及提升汽车品牌服务质量起着至关重要的作用。随着汽车电子化程度的不断提高&#xff0c;售后诊断所涉及的数据和流程愈发复杂&#xff0c;这就促使行业需要更加标准化、高效化…...

AI重构农业:从“面朝黄土“到“数字原野“的产业跃迁—读中共中央 国务院印发《加快建设农业强国规划(2024-2035年)》

在东北黑土地的万亩良田上&#xff0c;无人机编队正在执行精准施肥作业&#xff1b;在山东寿光的智慧大棚里&#xff0c;传感器网络实时调控着番茄生长的微环境&#xff1b;在云南的咖啡种植园中&#xff0c;区块链溯源系统记录着每粒咖啡豆的旅程。这场静默的农业革命&#xf…...