ObjectMapper 在 Spring 统一响应处理中的作用详解

ObjectMapper 是 Jackson 库的核心类,专门用于处理 JSON 数据的序列化(Java 对象 → JSON)和反序列化(JSON → Java 对象)。在你提供的代码中,它解决了字符串响应特殊处理的关键问题。

一、为什么需要 ObjectMapper?

问题背景

if (body instanceof String) {return mapper.writeValueAsString(Result.success(body));
}

这段代码处理的是当控制器返回纯字符串时的特殊情况。在 Spring MVC 中,不同类型的返回值有不同的处理方式:

返回值类型处理方式问题
对象/集合自动使用 JSON 转换器
字符串使用字符串转换器无法自动包装为 JSON

具体问题演示

假设有一个控制器:

@RestController
public class ExampleController {@GetMapping("/string")public String getString() {return "hello"; // 返回纯字符串}
}

没有 ObjectMapper 的情况

  1. beforeBodyWrite 返回 Result.success("hello")
  2. Spring 尝试使用 StringHttpMessageConverter 处理
  3. 因为 Result 不是字符串 → 类型转换错误!

二、ObjectMapper 如何解决这个问题

解决方案

mapper.writeValueAsString(Result.success(body));

分步解析

创建包装对象:Result result = Result.success("hello");
// 得到:{code:200, msg:"success", data:"hello"}
手动序列化为 JSON 字符串:String json = mapper.writeValueAsString(result);
// 得到:'{"code":200,"msg":"success","data":"hello"}'

 

  1.    最终返回字符串结果

    • 符合 StringHttpMessageConverter 的预期
    • 客户端收到标准 JSON 格式

序列化过程图解

Java对象: Result├─ code: 200├─ msg: "success"└─ data: "hello"↓ ObjectMapper 序列化
JSON字符串: '{"code":200,"msg":"success","data":"hello"}'

三、ObjectMapper 的核心能力

1. 序列化配置

// 创建时可配置(代码中通常静态初始化)
private static ObjectMapper mapper = new ObjectMapper();// 常用配置(可添加到静态初始化块)
static {// 美化输出(开发环境)mapper.enable(SerializationFeature.INDENT_OUTPUT);// 空值不参与序列化mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);// 日期格式标准化mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
}

2.支持复杂类型

// 嵌套对象
Result result = Result.success(new User("Alice", 25));
String json = mapper.writeValueAsString(result);
// 输出:{"code":200,"msg":"success","data":{"name":"Alice","age":25}}// 集合类型
List<String> list = Arrays.asList("A", "B", "C");
String json = mapper.writeValueAsString(Result.success(list));
// 输出:{"code":200,"msg":"success","data":["A","B","C"]}

3. 自定义序列化(高级)

// 自定义序列化器
public class MoneySerializer extends StdSerializer<BigDecimal> {public MoneySerializer() {super(BigDecimal.class);}@Overridepublic void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider provider) {gen.writeString(value.setScale(2) + "元");}
}// 注册自定义序列化器
mapper.registerModule(new SimpleModule().addSerializer(BigDecimal.class, new MoneySerializer()));// 使用效果
Result result = Result.success(new BigDecimal("123.456"));
String json = mapper.writeValueAsString(result);
// 输出:{"code":200,"msg":"success","data":"123.46元"}

四、实际应用场景

场景 1:统一处理日期格式

static {mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
}// 控制器返回
@GetMapping("/date")
public Date getDate() {return new Date(); // 返回日期对象
}// 处理结果
// 原始输出:1689987600000(时间戳)
// 处理后输出:"2023-07-22"

场景 2:处理枚举类型

public enum Status {ACTIVE, INACTIVE
}// 默认序列化
Status.ACTIVE → "ACTIVE"(枚举名)// 自定义序列化
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);// 在枚举中添加toString
public enum Status {ACTIVE("激活"), INACTIVE("禁用");private String desc;@Overridepublic String toString() {return desc;}
}// 输出结果:"激活"

场景 3:处理特殊字符

String text = "包含<特殊>字符&符号";
Result result = Result.success(text);// 未处理时:可能破坏JSON结构
// 处理后:自动转义为"包含\u003C特殊\u003E字符\u0026符号"

完整的最佳实践

@Slf4j
@ControllerAdvice
public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {// 静态初始化(线程安全)private static final ObjectMapper mapper = new ObjectMapper();static {// 基础配置mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);// 日期格式mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));// 注册Java 8时间模块mapper.registerModule(new JavaTimeModule());}@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {// 排除特定注解或类型return !returnType.hasMethodAnnotation(IgnoreWrap.class);}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {// 1. 已经是包装类型则直接返回if (body instanceof Result) {return body;}// 2. 处理空响应if (body == null) {return Result.success();}// 3. 特殊处理String类型if (body instanceof String) {// 设置正确的Content-Typeresponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);return mapper.writeValueAsString(Result.success(body));}// 4. 添加请求ID到响应头String requestId = request.getHeaders().getFirst("X-Request-ID");if (requestId != null) {response.getHeaders().add("X-Request-ID", requestId);}// 5. 默认包装return Result.success(body);}
}

总结

ObjectMapper 在统一响应处理中扮演着JSON 序列化引擎的角色,核心解决了两个关键问题:

  1. 统一响应格式:将各种类型的数据包装为标准结构
  2. 特殊类型处理:解决字符串返回值无法自动包装的问题

通过合理配置 ObjectMapper,可以实现:

  • 日期、枚举等特殊类型的格式化
  • 空值过滤、缩进美化等输出控制
  • 复杂对象和集合的序列化
  • 自定义序列化逻辑

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

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

相关文章

总结这几个月来我和AI一起开发并上线第一个应用的使用经验

副标题&#xff1a; 当“手残”前端遇到AI队友&#xff0c;我的音乐小站谱贝诞生记 大家好&#xff0c;我最近干了件“不务正业”的事——**独立开发并上线了一个完整的网站 作为一个前端“手残党”&#xff08;还在努力学习中&#x1f605;&#xff09;&#xff0c;这次能成功…

【大模型:知识图谱】--5.neo4j数据库管理(cypher语法2)

目录 1.节点语法 1.1.CREATE--创建节点 1.2.MATCH--查询节点 1.3.RETURN--返回节点 1.4.WHERE--过滤节点 2.关系语法 2.1.创建关系 2.2.查询关系 3.删除语法 3.1.DELETE 删除 3.2.REMOVE 删除 4.功能补充 4.1.SET &#xff08;添加属性&#xff09; 4.2.NULL 值 …

结构体指针与非指针 问题及解决

问题描述 第一段位于LCD.h和LCD.c中&#xff0c; 定义个一个结构体lcd_params&#xff0c;并直接给与指针名*p_lcd_params; 我发现我在调用这个结构体时&#xff0c;即在LCD.c中&#xff0c;使用指针类型定义的 static p_lcd_params p_array_lcd[LCD_NUM]; static p_lcd_par…

【设计模式-3.7】结构型——组合模式

说明&#xff1a;本文介绍结构型设计模式之一的组合模式 定义 组合模式&#xff08;Composite Pattern&#xff09;又叫作整体-部分&#xff08;Part-Whole&#xff09;模式&#xff0c;它的宗旨是通过将单个对象&#xff08;叶子节点&#xff09;和组合对象&#xff08;树枝…

【TMS570LC4357】之相关驱动开发学习记录2

系列文章目录 【TMS570LC4357】之工程创建 【TMS570LC4357】之工程配置修改 【TMS570LC4357】之HALCOGEN使用 【TMS570LC4357】之相关问题及解决 【TMS570LC4357】之相关驱动开发学习记录1 ——————————————————— 前言 记录笔者在第一次使用TMS570过程中对…

3D Gaussian splatting 05: 代码阅读-训练整体流程

目录 3D Gaussian splatting 01: 环境搭建3D Gaussian splatting 02: 快速评估3D Gaussian splatting 03: 用户数据训练和结果查看3D Gaussian splatting 04: 代码阅读-提取相机位姿和稀疏点云3D Gaussian splatting 05: 代码阅读-训练整体流程3D Gaussian splatting 06: 代码…

【黑马程序员uniapp】项目配置、请求函数封装

黑马程序员前端项目uniapp小兔鲜儿微信小程序项目视频教程&#xff0c;基于Vue3TsPiniauni-app的最新组合技术栈开发的电商业务全流程_哔哩哔哩_bilibili 参考 有代码&#xff0c;还有app、h5页面、小程序的演示 小兔鲜儿-vue3ts-uniapp-一套代码多端部署: 小兔鲜儿-vue3ts-un…

前端使用 preview 插件预览docx文件

目录 前言一 引入插件二 JS 处理 前言 前端使用 preview 插件预览docx文件 一 引入插件 建议下载至本地&#xff0c;静态引入&#xff0c;核心的文件已打包&#xff08;前端使用 preview 插件预览docx文件&#xff09;&#xff0c;在文章目录处下载至本地&#xff0c;复制在项…

如何在运动中保护好半月板?

文章目录 引言I 半月板的作用稳定作用缓冲作用润滑作用II 在跳绳运动中保护好半月板III 半月板损伤自测IV 半月板“杀手”半月板损伤必须满足四个因素:消耗品引言 膝盖是连接大腿骨和小腿骨的地方,在两部分骨头的连接处,垫着两片半月形的纤维软骨板,这就是半月板。半月板分…

安科瑞防逆流方案落地内蒙古中高绿能光伏项目,筑牢北疆绿电安全防线

一、项目概况 内蒙古阿拉善中高绿能能源分布式光伏项目&#xff0c;位于内蒙古乌斯太镇&#xff0c;装机容量为7MW&#xff0c;采用自发自用、余电不上网模式。 用户配电站为35kV用户站&#xff0c;采用两路电源单母线分段系统。本项目共设置12台35/0.4kV变压器&#xff0c;在…

1.3 fs模块详解

fs 模块详解 Node.js 的 fs 模块提供了与文件系统交互的能力&#xff0c;是服务器端编程的核心模块之一。它支持同步、异步&#xff08;回调式&#xff09;和 Promise 三种 API 风格&#xff0c;可满足不同场景的需求。 1. 模块引入 const fs require(fs); // 回调…

LeetCode 70 爬楼梯(Java)

爬楼梯问题&#xff1a;动态规划与斐波那契的巧妙结合 问题描述 假设你正在爬楼梯&#xff0c;需要爬 n 阶才能到达楼顶。每次你可以爬 1 或 2 个台阶。求有多少种不同的方法可以爬到楼顶&#xff1f; 示例&#xff1a; n 2 → 输出 2&#xff08;1阶1阶 或 2阶&#xff0…

【学习分享】shell基础-参数传递

参数传递 我们可以在执行 Shell 脚本时&#xff0c;向脚本传递参数&#xff0c;脚本内获取参数的格式为 $n&#xff0c;n 代表一个数字&#xff0c;1 为执行脚本的第一个参数&#xff0c;2 为执行脚本的第二个参数。 例如可以使用 $1、$2 等来引用传递给脚本的参数&#xff0…

Fluence推出“Pointless计划”:五种方式参与RWA算力资产新时代

2025年6月1日&#xff0c;去中心化算力平台 Fluence 正式宣布启动“Pointless 计划”——这是其《Fluence Vision 2026》战略中四项核心举措之一&#xff0c;旨在通过贡献驱动的积分体系&#xff0c;激励更广泛的社区参与&#xff0c;为用户带来现实世界资产&#xff08;RWA&am…

Excel数据分析:基础

在现代办公环境中&#xff0c;Excel 是一款不可或缺的工具&#xff0c;它是 Microsoft&#xff08;微软&#xff09;开发的电子表格软件&#xff0c;用于处理和分析结构化数据。市场上还有其他类似的软件&#xff0c;如 Google Sheets 和 Apple Numbers&#xff0c;但 Excel 以…

12V降5V12A大功率WD5030A,充电器、便携式设备、网络及工业领域的理想选择

WD5030A 高效单片同步降压型直流 / 直流转换器 一、芯片核心概述 WD5030A 是一款高性能同步降压型 DC/DC 转换器&#xff0c;采用 平均电流模式控制架构&#xff08;带频率抖动功能&#xff09;&#xff0c;具备以下核心优势&#xff1a; 精准电流控制&#xff1a;快速响应负…

企业级AI迈入黄金时代,企业该如何向AI“蝶变”?

科技云报到原创。 近日&#xff0c;微软&#xff08;MSFT.US&#xff09;在最新全员大会上高调展示企业级AI业务进展&#xff0c;其中与巴克莱银行达成的10万份Copilot许可证交易成为焦点。 微软首席商务官贾德森阿尔索夫在会上披露&#xff0c;这家英国金融巨头已签约采购相…

Java编程课(一)

Java编程课 一、java简介二、Java基础语法2.1 环境搭建2.2 使用Intellij IDEA新建java项目2.3 Java运行介绍2.4 参数说明2.5 Java基础语法2.6 注释2.7 变量和常量一、java简介 Java是一种广泛使用的高级编程语言,最初由Sun Microsystems于1995年发布。它被设计为具有简单、可…

【Java Web】速通Tomcat

参考笔记:JavaWeb 速通Tomcat_tomcat部署java项目-CSDN博客 目录 一、Tomcat服务 1. 下载和安装 2. 启动Tomcat服务 3. 启动Tomcat服务的注意事项 4. 关闭Tomcat服务 二、Tomcat的目录结构 1. bin 🌟 2. conf 🌟 3. lib 4. logs 5. temp 6. webapps 7. work 三、Web项目…

Mysql 身份认证绕过漏洞 CVE-2012-2122

前言&#xff1a;CVE-2012-2122 是一个影响 MySQL 和 MariaDB 的身份验证漏洞&#xff0c;存在于特定版本中 vulhub/mysql/CVE-2012-2122/README.zh-cn.md at master vulhub/vulhubhttps://github.com/vulhub/vulhub/blob/master/mysql/CVE-2012-2122/README.zh-cn.md 任务一…