MVC入门(5)-- HttpMessageConverter 消息转换器

概念

HttpMessageConverter 是 Spring 框架中用于处理 HTTP 请求和响应数据的核心接口,负责在 Java 对象与 HTTP 消息体(请求体或响应体)之间进行双向转换。简单来说,它是 Spring 用来将 HTTP 请求中的原始数据(如 JSON、XML、表单数据等)转换为 Java 对象,或者将 Java 对象转换为 HTTP 响应数据的“翻译器”

就是返回的是 UserVO 对象,但是最后传输到前端时,变成了 Json 字符串

核心作用

  • 序列化和反序列化
    • 请求:将客户端发送的 HTTP 请求体(如 JSON 字符串)反序列化为 Java 对象(如 User 类)
    • 响应:将 Java 对象(如 User 对象)序列化为客户端需要的格式(如 JSON、XML)
  • 内容协商:根据客户端请求的 Content-Type(请求数据类型)和 Accept(期望的响应数据类型),自动选择匹配的 HttpMessageConverter 处理数据格式

接口源码

package org.springframework.http.converter;import java.io.IOException;
import java.util.List;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;public interface HttpMessageConverter<T> {boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);List<MediaType> getSupportedMediaTypes();default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {return !this.canRead(clazz, (MediaType)null) && !this.canWrite(clazz, (MediaType)null) ? Collections.emptyList() : this.getSupportedMediaTypes();}T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
}

根据源码解释作用:

  • 在请求时,通过请求头 Content-Type 上,表示请求内容(Request Body)的内容类型。这样,Spring MVC 会从 HttpMessageConverter 数组中,通过 canRead(clazz, mediaType) 方法,判断是否够读取指定的 mediaType 内容类型,转换成对应的 clazz 对象。如果可以的话,则调用 read(Class<? extends T> clazz, HttpInputMessage inputMessage) 方法,读取请求内容,转换成 clazz 对象。
  • 在响应时,通过请求头 Accept 上,表示请求内容(Response Body)的内容类型。Spring MVC 会从 HttpMessageConverter 数组中,通过 canWrite(clazz, mediaType) 方法,判断是否能够将 clazz 对象,序列化成 mediaType 内容类型。如果可以的话,则调用 write(contentType, outputMessage) 方法,将 clazz 对象,序列化成 contentType 内容类型,写入到响应。

常见实现方法

内置了多种 HttpMessageConverter 实现,支持不同数据格式

实现类作用
MappingJackson2HttpMessageConverter处理 JSON 格式(基于 Jackson 库)
GsonHttpMessageConverter处理 JSON 格式(基于 Gson 库)
Jaxb2RootElementHttpMessageConverter处理 XML 格式(基于 JAXB)
StringHttpMessageConverter处理纯文本(如 text/plain
FormHttpMessageConverter处理表单数据(application/x-www-form-urlencoded

案例

同时支持 JSON/XML 格式提交数据,也同时支持 JSON/XML 格式响应数据的案例

XmlMapper 是 Jackson 提供的用于处理 XML 的类,位于 jackson-dataformat-xml 模块中。默认情况下,SpringBoot 并不会自动包含该模块,需要手动添加相关依赖。

配置

重写 MappingJackson2XmlHttpMessageConverter 配置类,新增 XML 格式

@Configuration
@RequiredArgsConstructor
public class SpringMVCConfiguration implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {Jackson2ObjectMapperBuilder xmlBuilder = Jackson2ObjectMapperBuilder.xml();xmlBuilder.indentOutput(true);converters.add(new MappingJackson2XmlHttpMessageConverter(xmlBuilder.build()));}
}

接口

新增接口

@RestController
@RequestMapping("/users")
public class UserController {@PostMapping(value = "/addXml",// ↓ 增加 "application/xml"、"application/json" ,针对 Content-Type 请求头consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},// ↓ 增加 "application/xml"、"application/json" ,针对 Accept 请求头produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})public UserVO addXml(@RequestBody UserAddDTO addDTO) {return new UserVO().setUsername("username: " + addDTO.getUsername());}}
  • consumes 属性:限制可接受的请求内容类型,不匹配时返回 415 Unsupported Media Type 状态码
  • produces 属性:限制可返回的响应内容类型,不匹配时返回 406 Not Acceptable 状态码

请求接口

POST http://localhost:8080/users/addXml  
Content-Type: application/xml  
Accept: application/xml  <user>  <id>1</id>  <username>张三</username>  <password>123456</password>  
</user>

返回

<Result><code>200</code><msg>成功</msg><data><id/><username>username: 张三</username></data>
</Result>

Fastjson 依赖

在 SpringBoot 中默认是用 Jackson 作为对 JSON 的序列化和反序列化,即默认使用 MappingJackson2HttpMessageConverter(基于 Jackson 库)处理 JSON 数据,有时候可以使用第三方依赖来替换 Jackson 实现对 JSON 的序列化和反序列化,比如 Fastjson 依赖。

Fastjson 是阿里巴巴开源的一款高性能 Java JSON 库,用于实现 Java 对象与 JSON 数据之间的序列化(对象 → JSON)和反序列化(JSON → 对象)。它的核心目标是提供极致的 JSON 处理性能(号称“最快的 JSON 库”),同时支持复杂的 Java 类型(如泛型、枚举、Lambda 表达式)和灵活的配置。

使用原因

  • 性能优势
    • 更快的处理速度:在序列化和反序列化时通常比 Jackson 更快(尤其是处理大对象或复杂结构时),适合高并发场景
    • 低内存占用:Fastjson 的设计优化了内存使用,减少 GC 压力
  • 功能丰富性
    • 支持复杂类型:如泛型、LocalDateTime、枚举等,无需额外配置
    • 灵活的注解:通过 @JSONField 注解可自定义字段名称、格式、忽略字段等
    • 定制化配置
  • 易用性
    • 简洁的API:Fastjson 提供类似 JSON.toJSONString(obj) 和 JSON.parseObject(json, User.class) 的直接方法
    • 中文支持友好

配置过程

添加 Fastjson 依赖

<dependency>  <groupId>com.alibaba</groupId>  <artifactId>fastjson</artifactId>  <version>2.0.50</version>  
</dependency>

添加 Fastjson 依赖后,需要排除掉默认 Jackson 依赖(如果你不需要它的话)

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-json</artifactId></exclusion></exclusions>
</dependency>	

配置 Fastjson

@Configuration
@RequiredArgsConstructor
public class SpringMVCConfiguration implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 定义一个convert转换消息的对象FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();// 添加fastjson的配置信息FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setSerializerFeatures(// 格式化输出SerializerFeature.PrettyFormat,// 输出空字段SerializerFeature.WriteMapNullValue,// 日期格式化SerializerFeature.WriteDateUseDateFormat);fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);// 处理中文乱码问题List<MediaType> fastMediaTypes = new ArrayList<>();// fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);fastMediaTypes.add(MediaType.APPLICATION_JSON);fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);// 在converters中添加fastjson的配置信息converters.add(0, fastJsonHttpMessageConverter);}}

fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8) 会有 'APPLICATION_JSON_UTF8' is deprecated提示,因为 Framework 自 5.2 起,推荐使用 MediaType.APPLICATION_JSON,因为主要浏览器(如 Chrome)现在遵循规范,能够正确解析 UTF-8 特殊字符,而无需在 Content-Type 中指定 charset=UTF-8 参数。

setSerializerFeatures 方法

config.setSerializerFeatures 是 Fastjson 中用于配置 JSON 序列化行为的核心方法,它通过启用或禁用不同的 SerializerFeature 枚举值,控制 Java 对象转换为 JSON 字符串时的具体规则

Fastjson 默认的序列化行为较为简洁(例如不输出空字段、日期使用时间戳格式),但在实际开发中,我们通常需要更灵活的配置。

场景示例默认行为配置特性后的行为
空字段处理忽略 null 字段输出 {"name": null}
日期格式日期转为时间戳(如 1672531200000转为 "2023-01-01 00:00:00"
JSON 可读性压缩输出(无缩进换行)格式化输出(带缩进和换行)
枚举类型处理输出枚举的 name() 值输出枚举的 ordinal() 值
  • PrettyFormat:格式化 JSON 输出,添加换行和缩进,使 JSON 更易阅读
// 未启用 PrettyFormat
{"name":"Alice","age":25}// 启用 PrettyFormat
{"name": "Alice","age": 25
}
  • WriteMapNullValue:序列化时保留值为 null 的字段
// 未启用 WriteMapNullValue
{"name":"Alice"}// 启用 WriteMapNullValue
{"name":"Alice", "age":null}
  • WriteDateUseDateFormat:将 Date 类型字段按指定格式(如 yyyy-MM-dd HH:mm:ss)序列化
config.setDateFormat("yyyy-MM-dd");
// 输出
{"birthday": "2023-01-01"}
  • WriteEnumUsingToString:将枚举类型按 toString() 方法的值输出,而非默认的 name()
enum Status { OPEN("开启"), CLOSE("关闭"); }
// 默认输出 "OPEN"
// 启用后输出 "开启"

参考

  • 芋道 Spring Boot SpringMVC 入门 | 芋道源码 —— 纯源码解析博客
  • 使用HttpMessageConverter实现HTTP的序列化和反序列化 - duanxz - 博客园
  • Title Unavailable | Site Unreachable

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

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

相关文章

Spark,连接MySQL数据库,添加数据,读取数据

以下是使用Spark连接MySQL数据库、添加数据和读取数据的步骤&#xff08;基于Scala API&#xff09;&#xff1a; 1. 准备工作 - 添加MySQL驱动依赖 在Spark项目中引入MySQL Connector JAR包&#xff08;如 mysql-connector-java-8.0.33.jar &#xff09;&#xff0c;或通过Sp…

关于 APK 反编译与重构工具集

一、apktool — APK 解包 / 重打包 apktool 是一款开源的 Android APK 工具&#xff0c;用于&#xff1a; 反编译 APK 查看资源和布局文件 生成 smali 文件&#xff08;DEX 的反汇编&#xff09; 对 APK 进行修改后重新打包 它不能还原 Java 源码&#xff0c;只能将 D…

[解决方案] Word转PDF

背景&#xff1a; 之前做过一些pdf导出&#xff0c; 客户提了一个特别急的需求&#xff0c; 要求根据一个模版跟一个csv的数据源&#xff0c; 批量生成PDF&#xff0c; 因为之前用过FOP&#xff0c; 知道调整样式需要特别长的时间&#xff0c; 这个需求又特别急&#xff0c; 所…

01 基本介绍及Pod基础

01 查看各种资源 01-1 查看K8s集群的内置资源 [rootmaster01 ~]# kubectl api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 …

19 C 语言位运算、赋值、条件、逗号运算符详解:涵盖运算符优先级与复杂表达式计算过程分析

1 位运算符 位运算符是对整数的二进制表示&#xff08;补码形式&#xff09;进行逐位操作的运算符。以下是主要的位运算符及其功能描述&#xff1a; 运算符描述操作数个数副作用&按位与2无|按位或2无^按位异或2无~按位取反1无<<按位左移2无>>按位右移2无 1.1…

哈希查找方法

已知哈希表长度为11&#xff0c;哈希函数为H&#xff08;key&#xff09;&#xff1d;key&#xff05;11&#xff0c;随机产生待散列的小于50的8个元素&#xff0c;同时采用线性探测再散列的方法处理冲突。任意输入要查找的数据&#xff0c;无论是否找到均给出提示信息。 int f…

JavaScript性能优化实战(10):前端框架性能优化深度解析

引言 React、Vue、Angular等框架虽然提供了强大的抽象和开发效率,但不恰当的使用方式会导致严重的性能问题,针对这些问题,本文将深入探讨前端框架性能优化的核心技术和最佳实践。 React性能优化核心技术 React通过虚拟DOM和高效的渲染机制提供了出色的性能,但当应用规模…

类和对象------2

目录 一. C面向对象模型初探1 .成员变量和函数的存储 二 this指针1 &#xff09;this指针工作原理2 &#xff09;this指针的使用3&#xff09; const修饰成员函数4 &#xff09;const修饰对象(常对象) 3.友元1 )友元语法2) 课堂练习 4 强化训练(数组类封装) 四 运算符重载&…

量子计算在金融科技中的应用前景

随着量子计算技术的飞速发展&#xff0c;其在各行业的应用潜力逐渐显现&#xff0c;金融科技领域更是备受关注。量子计算的强大计算能力有望为金融行业带来前所未有的变革&#xff0c;从风险评估到投资组合优化&#xff0c;从高频交易到加密技术&#xff0c;量子计算都可能成为…

Redisson 四大核心机制实现原理详解

一、可重入锁&#xff08;Reentrant Lock&#xff09; 可重入锁是什么&#xff1f; 通俗定义 可重入锁类似于一把“智能锁”&#xff0c;它能识别当前的锁持有者是否是当前线程&#xff1a; 如果是&#xff0c;则允许线程重复获取锁&#xff08;重入&#xff09;&#xff0c;并…

srs-7.0 支持obs推webrtc流

demo演示 官方教程: https://ossrs.net/lts/zh-cn/blog/Experience-Ultra-Low-Latency-Live-Streaming-with-OBS-WHIP 实现原理就是通过WHIP协议来传输 SDP信息 1、运行 ./objs/srs -c conf/rtc.conf 2、obs推流 3、web端播放webrtc流 打开web:ht

面试题——JDBC|Maven|Spring的IOC思想|DI思想|SpringMVC

目录 一、JDBC 1、jdbc连接数据库的基本步骤&#xff08;掌握**&#xff09; 2、Statement和PreparedStatement的区别 &#xff08;掌握***&#xff09; 二、Maven 1、maven的作用 2、maven 如何排除依赖 3、maven scope作用域有哪些&#xff1f; 三、Spring的IOC思想 …

从代码学习数学优化算法 - 拉格朗日松弛 Python版

文章目录 前言1. 问题定义 (Problem Definition)2. 拉格朗日松弛 (Lagrangian Relaxation)3. 拉格朗日对偶问题 (Lagrangian Dual)4. 次梯度优化 (Subgradient Optimization)5. Python 代码实现导入库和问题定义辅助函数:求解拉格朗日松弛子问题次梯度优化主循环结果展示与绘图…

密码学实验

密码学实验二 一、实验目的&#xff08;本次实验所涉及并要求掌握的知识点&#xff09; 掌握RSA算法的基本原理并根据给出的RSA算法简单的实现代码源程序,以及能够使用RSA对文件进行加密。掌握素性测试的基本原理&#xff0c;并且会使用Python进行简单的素性测试以及初步理解…

力扣面试150题-- 从中序与后序遍历序列构造二叉树

Day 44 题目描述 思路 这题类似与昨天那题&#xff0c;首先来复习一下&#xff0c;后序遍历&#xff0c;对于后序遍历每一个元素都满足以下规律&#xff1a; &#xff08;左子树&#xff09;&#xff08;右子树&#xff09;&#xff08;根&#xff09;&#xff0c;那么我们直…

2区组的2水平析因实验的混区设计

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著傅珏生译)第7章2k析因的区组化和混区设计第7.4节的python解决方案。本文尽量避免重复书中的理论&#xff0c;着于提供python解决方案&#xff0c;并与原书的运算结果进行对比。您可以从Detail 下载实验设计与分析…

反向传播算法——矩阵形式递推公式——ReLU传递函数

总结反向传播算法。 来源于https://udlbook.github.io/udlbook/&#xff0c;我不明白初始不从 x 0 \boldsymbol{x}_0 x0​开始&#xff0c;而是从 z 0 \boldsymbol{z}_0 z0​开始&#xff0c;不知道怎么想的。 考虑一个深度神经网络 g [ x i , ϕ ] g[\boldsymbol{x}_i, \bold…

2025年PMP 学习二十三 16章 高级项目管理

2025年PMP 学习二十三 16章 高级项目管理 文章目录 2025年PMP 学习二十三 16章 高级项目管理高级项目管理战略管理战略管理的组成要素&#xff1a;企业战略转化为战略行动的阶段&#xff1a; 组织战略类型战略组织类型组织级项目管理OPM&#xff08;公司项目管理&#xff09; 组…

Journal of Real-Time Image Processing 投稿过程

投稿要求双栏12页以内(包括参考文献)&#xff0c;这个排版要求感觉不是很严格&#xff0c;我当时就是用普通的双栏的格式去拍的版&#xff0c;然后就提交了&#xff0c;也没单独去下载模版。 投稿过程 12.12 Submission received 12.12 Submission is under technical check 1…

t检验详解:原理、类型与应用指南

t检验详解&#xff1a;原理、类型与应用指南 t检验&#xff08;t-test&#xff09;是一种用于比较两组数据均值是否存在显著差异的统计方法&#xff0c;适用于数据近似正态分布且满足方差齐性的场景。以下从核心原理、检验类型、实施步骤到实际应用进行系统解析。 一、t检验的…