spring mvc @ResponseBody 注解轉換為 JSON 的原理與實現詳解


在這里插入圖片描述

@ResponseBody 注解轉換為 JSON 的原理與實現詳解


1. 核心作用

@ResponseBody 是 Spring MVC 的一個注解,用于將方法返回的對象直接序列化為 HTTP 響應體(如 JSON 或 XML),而不是通過視圖解析器渲染為視圖(如 HTML)。

  • 關鍵作用
    • 跳過視圖解析階段,直接返回數據。
    • 觸發 消息轉換器(HttpMessageConverter) 將對象轉換為指定格式(如 JSON)。

2. 工作流程詳解
步驟 1:方法返回對象
@RestController
public class UserController {@GetMapping("/user")public User getUser() {return new User("John", 25); // 返回 Java 對象}
}
步驟 2:觸發消息轉換
  • Spring 檢測到 @ResponseBody:跳過視圖解析,直接進入消息轉換階段。
  • 選擇合適的 HttpMessageConverter
    • 根據 返回對象類型請求的 Accept 頭(如 application/json)選擇轉換器。
    • 默認情況下,Spring Boot 自帶的 Jackson 庫 提供的 MappingJackson2HttpMessageConverter 會被選中。
步驟 3:Jackson 序列化對象
  • Jackson 的 ObjectMapper:負責將 Java 對象轉換為 JSON 字符串。
  • 序列化過程
    1. 遍歷對象的 getter 方法字段
    2. 根據注解(如 @JsonProperty)和配置(如日期格式)處理屬性。
    3. 忽略 transient 字段或 @JsonIgnore 標記的字段。
// 示例 JSON 輸出
{"name": "John","age": 25
}

3. 完整代碼示例

3.1 實體類(User.java)
public class User {private String name;private int age;// 構造函數、getter 和 setter 方法public User(String name, int age) {this.name = name;this.age = age;}// 省略 getter/setter
}
3.2 控制器(UserController.java)
import org.springframework.web.bind.annotation.*;@RestController // 等效于 @Controller + @ResponseBody
public class UserController {@GetMapping("/user")public User getUser() {return new User("John", 25); // 直接返回對象,由 @ResponseBody 觸發轉換}@PostMapping("/user")public User createUser(@RequestBody User user) {// 處理 POST 請求,將 JSON 反序列化為 User 對象return user;}
}
3.3 測試請求
# GET 請求獲取 JSON
curl http://localhost:8080/user
# 輸出:{"name":"John","age":25}# POST 請求發送 JSON
curl -X POST -H "Content-Type: application/json" -d '{"name":"Jane","age":30}' http://localhost:8080/user

4. 消息轉換器(HttpMessageConverter)詳解

Spring MVC 通過 HttpMessageConverter 完成對象到 HTTP 響應的轉換。

  • 核心接口HttpMessageConverter<T>

    • canRead():判斷是否支持反序列化(如 JSON → 對象)。
    • canWrite():判斷是否支持序列化(如對象 → JSON)。
    • write():實際執行序列化操作。
  • 常用實現類

    類名作用默認支持格式
    MappingJackson2HttpMessageConverterJSON 轉換(依賴 Jackson 庫)application/json
    MappingJackson2XmlHttpMessageConverterXML 轉換(需額外配置)application/xml
    StringHttpMessageConverter字符串轉換text/plain

5. Jackson 配置與自定義

通過自定義 ObjectMapper 可控制 JSON 序列化行為:

5.1 配置示例
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;@Configuration
public class JacksonConfig {@Beanpublic ObjectMapper objectMapper() {ObjectMapper mapper = new ObjectMapper();// 設置日期格式mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));// 忽略未找到的字段(反序列化時)mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);return mapper;}
}
5.2 常用注解
注解作用
@JsonProperty指定 JSON 鍵名(覆蓋字段名)。
@JsonFormat定制日期/數字格式。
@JsonInclude控制字段是否參與序列化(如 @JsonInclude(JsonInclude.Include.NON_NULL))。
@JsonIgnore忽略字段。

6. 常見問題與解決方案

Q1:為什么 JSON 中沒有某個字段?
  • 可能原因
    • 字段沒有 getter 方法。
    • 字段被 @JsonIgnoretransient 修飾。
    • @JsonInclude 配置排除了該字段(如 NON_NULL 且值為 null)。
Q2:如何處理循環引用?
  • 解決方案
    @JsonManagedReference // 主對象(單向引用)
    @JsonBackReference // 被引用對象(忽略反向引用)
    
Q3:如何自定義序列化邏輯?
  • 自定義序列化器
    public class CustomSerializer extends JsonSerializer<Date> {@Overridepublic void serialize(Date value, JsonGenerator gen, SerializerProvider serializers)throws IOException {gen.writeString(new SimpleDateFormat("yyyy-MM-dd").format(value));}
    }
    
Q4:如何禁用 HTML 轉義?
  • 配置
    @Bean
    public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();converter.getObjectMapper().disable(SerializationFeature.ESCAPE_NON_ASCII);return converter;
    }
    

7. 總結表格
環節關鍵組件職責
觸發轉換@ResponseBody告知 Spring 直接返回數據,跳過視圖解析。
選擇轉換器HttpMessageConverter根據返回類型和 Accept 頭選擇合適的轉換器。
序列化JacksonObjectMapper將 Java 對象轉換為 JSON 字符串。
配置擴展自定義 ObjectMapper精細控制序列化格式、日期、忽略策略等。

總結

@ResponseBody 通過結合 HttpMessageConverter 和 Jackson,將 Java 對象無縫轉換為 JSON 響應。掌握其工作原理和配置方法,可以靈活處理 RESTful API 的數據格式化需求。對于復雜場景(如自定義序列化、處理循環引用),可通過 Jackson 的注解和配置進一步優化。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/900737.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/900737.shtml
英文地址,請注明出處:http://en.pswp.cn/news/900737.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV——圖像融合

OpenCV——圖像融合 一、引言1.1 圖像融合分類 二、C代碼實現三、效果展示3.1 標準球3.2 鋁制底座 一、引言 在許多計算機視覺應用中(例如機器人運動和醫學成像)&#xff0c;需要將來自多幅圖像的相關信息集成到一幅圖像中。這種圖像融合將提供更高的可靠性、準確性和數據質量…

機器學習之PCA主成分分析詳解

文章目錄 引言一、PCA的概念二、PCA的基本數學原理2.1 內積與投影2.2 基2.3 基變換2.4 關鍵問題及優化目標2.5 方差2.6 協方差2.7 協方差矩陣2.8 協方差矩陣對角化 三、PCA執行步驟總結四、PCA參數解釋五、代碼實現六、PCA的優缺點七、總結 引言 在機器學習領域&#xff0c;我…

springboot自動配置原理例子講解

Spring Boot 的自動配置是其核心特性之一&#xff0c;它幫助開發者**"開箱即用"**地使用各種第三方庫或 Spring 組件&#xff0c;而無需手動配置 Bean。這一切的背后&#xff0c;都依賴于 Spring Boot 的自動配置機制。 我們分兩部分來說&#xff1a; Spring Boot 自…

一款基于 .NET 8 + Vue 開源的、企業級中后臺權限管理系統

前言 今天大姚給大家分享一款基于 .NET 8 Vue 開源、前后端分離的企業級中后臺權限管理系統&#xff0c;助力快速完成常規業務需求開發&#xff1a;ApeVolo.Admin。 項目介紹 ApeVolo.Admin 一款基于.NET 8、SqlSugar、Vue、Elment UI、RBAC、前后端分離、開源&#xff08;…

vue3騰訊云直播 前端推流

1、在index.html文件中引入&#xff08;在body體中&#xff09; <script src"https://video.sdk.qcloudecdn.com/web/TXLivePusher-2.1.1.min.js" charset"utf-8"></script> 2、vue文件中&#xff0c;添加video推流&#xff08;我用的推流地…

藍疊模擬器過檢測全攻略

BlueStacks藍疊MagiskLsposed安裝和過應用檢測教程 藍疊MagiskLsposed安裝和過應用檢測教程 引言 藍疊模擬器憑借其出色的性能和兼容性&#xff0c;在電腦上運行安卓應用和游戲方面備受青睞。然而&#xff0c;眾多應用和游戲為確保公平性與安全性&#xff0c;加入了模擬器檢測…

Flutter Invalid constant value.

0x00 問題 參數傳入變量&#xff0c;報錯&#xff01; 代碼 const Padding(padding: EdgeInsets.all(20),child: GradientProgressIndicator(value: _progress), ),_progress 參數報錯&#xff1a;Invalid constant value. 0x01 原因 這種情況&#xff0c;多發生于&#xff…

搜廣推校招面經七十一

滴滴算法工程師面經 一、矩陣分解的原理與優化意義 矩陣分解在推薦系統中是一個非常核心的方法&#xff0c;尤其是在 協同過濾(Collaborative Filtering) 中。我們可以通過用戶對物品的評分行為來推測用戶的喜好&#xff0c;從而推薦他們可能喜歡的內容。 1.1. 直觀理解&…

實習技能記錄【2】-----LVGL[基本概念]

LVGL主要概念 1. Screen (屏幕): 概念: 屏幕是 LVGL 應用程序中的頂層容器。它是用戶界面的根對象&#xff0c;所有的可見 UI 元素最終都會添加到某個屏幕上&#xff08;通常是活動屏幕&#xff09;。 功能: 作為其他 UI 元素的父對象。 可以擁有自己的背景顏色、背景圖片等樣…

【c++11】c++11新特性(上)(列表初始化、右值引用和移動語義、類的新默認成員函數、lambda表達式)

&#x1f31f;&#x1f31f;作者主頁&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所屬專欄&#xff1a;C 目錄 前言 一、列表初始化 1. 大括號初始化 2. initializer_list 二、右值引用和移動語義 1. 左值和右值 2. 左值引用和右值引用 引用延長生命周期 左…

軟考中級-軟件設計師 2022年下半年上午題真題解析:通關秘籍+避坑指南

&#x1f4da; 目錄&#xff08;快速跳轉&#xff09; 選擇題&#xff08;上午題&#xff09;&#xff08;每題1分&#xff0c;共75分&#xff09;一、 計算機系統基礎知識 &#x1f5a5;?&#x1f4bb; 題目1&#xff1a;計算機硬件基礎知識 - RISC&#xff08;精簡指令集計算…

基于MCP協議調用的大模型agent開發02

目錄 在AI agent的開發過程中&#xff0c;如何使用mcp服務器作為大模型的工具調用‘百寶箱’&#xff1f; FastAPI FastMCP 本系列&#xff1a; 基于MCP協議調用的大模型agent開發01-CSDN博客 基于MCP協議調用的大模型agent開發02-CSDN博客 在AI agent的開發過程中&#xff0c;…

ES6(8) Fetch API 詳解

1. Fetch API 簡介 fetch 是 ES6 提供的基于 Promise 的 API&#xff0c;用于發送 HTTP 請求并處理服務器響應數據。與傳統的 XMLHttpRequest 相比&#xff0c;fetch 語法更加簡潔&#xff0c;使用 Promise 進行異步處理&#xff0c;避免了回調地獄。 1.1 fetch() 的基本用法 …

原生SSE實現AI智能問答+Vue3前端打字機流效果

實現流程&#xff1a; 1.用戶點擊按鈕從右側展開抽屜&#xff08;drawer&#xff09;&#xff0c;打開模擬對話框 2.用戶輸入問題&#xff0c;點擊提問按鈕&#xff0c;創建一個SSE實例請求后端數據&#xff0c;由于SSE是單向流&#xff0c;所以每提一個問題都需要先把之前的實…

CUDA 工具鏈將全面原生支持 Python

根據 NVIDIA 在 2025 年 GTC 大會上的官宣&#xff0c;CUDA 工具鏈將全面原生支持 Python 編程&#xff0c;這一重大更新旨在降低 GPU 編程門檻&#xff0c;吸引更廣泛的 Python 開發者進入 CUDA 生態。以下是核心信息整合&#xff1a; 1. 原生支持的意義與背景 無需 C/C 基礎…

jupyter notebook 顯示conda虛擬環境

使用 nb_conda_kernels 安裝 nb_conda_kernels&#xff1a;這個包可以自動從你的 Conda 環境中發現并列出內核。 conda activate base # 確保你在 base 環境或任何其他環境中安裝 conda install nb_conda_kernels顯示jupyternotebook當前所在的位置。

【AI】MCP概念

一文講透 MCP&#xff08;附 Apifox MCP Server 內測邀請&#xff09; 7分鐘講清楚MCP是什么&#xff1f;統一Function calling規范&#xff0c;工作量銳減至1/6&#xff0c;人人手搓Manus&#xff01;&#xff1f; | 一鍵鏈接千臺服務器&#xff0c;幾行代碼接入海量外部工具…

WSL1升級到WSL2注意事項

今天要在WSL上安裝docker&#xff0c;因為機器上安裝了wsl1&#xff0c;docker安裝后啟動不了&#xff0c;通過詢問deepseek發現docker只能在wsl2上安裝&#xff0c;因此就想著將本機的wsl1升級到wsl2。 確保你的 Windows 系統是 Windows 10&#xff08;版本 1903 及以上&…

Pycharm常用快捷鍵總結

主要是為了記錄windows下的PyCharm的快捷鍵&#xff0c;里面的操作都試過了功能描述會增加備注。 文件操作 快捷鍵功能描述Ctrl N新建文件Ctrl Shift N根據名稱查找文件Ctrl O打開文件Ctrl S保存當前文件Ctrl Shift S另存為Alt F12打開終端&#xff08;Terminal&…

電池分選機:新能源時代的品質守護者|深圳比斯特自動化

在這個新能源蓬勃發展的時代&#xff0c;電池作為能量的存儲與釋放單元&#xff0c;其性能與質量直接關系到整個系統的穩定運行與效率提升。而電池分選機&#xff0c;作為電池生產流程中的關鍵一環&#xff0c;正扮演著品質守護者的角色&#xff0c;為新能源產業的高質量發展保…