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.pswp.cn/diannao/83868.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83868.shtml
英文地址,請注明出處:http://en.pswp.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檢驗的…