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
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83686.shtml
英文地址,請注明出處:http://en.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 任務一…