什么是 JSON?學習JSON有什么用?在springboot項目里如何實現JSON的序列化和反序列化?

作為一個學習Javaweb的新手,理解JSON的序列化和反序列化非常重要,因為它在現代Web開發,特別是Spring Boot中無處不在。

什么是 JSON?

首先,我們簡單了解一下JSON (JavaScript Object Notation)。
JSON 是一種輕量級的數據交換格式。它基于JavaScript編程語言的一個子集,但是獨立于語言,也就是說,幾乎所有的編程語言都有解析和生成JSON數據的庫。

JSON 的主要特點:

  • 易于人閱讀和編寫。

  • 易于機器解析和生成。

  • 常用于前后端之間的數據交換(比如瀏覽器和服務器之間)、API之間的數據傳輸。

  • 基本結構是:

    • 對象 (Object): 由鍵值對(key: value)組成,鍵是字符串,值可以是字符串、數字、布爾值、數組、對象或 null。對象用花括號 {} 包圍。

      {"name": "張三","age": 30,"isStudent": false
      }
      
    • 數組 (Array): 由有序的值(可以是任何JSON類型)組成。數組用方括號 [] 包圍。

      ["蘋果","香蕉","橙子"
      ]
      
    • 值 (Value): 字符串、數字、布爾值 (true/false)、null、對象或數組。

什么是 序列化 (Serialization)?

概念: 將一個Java對象轉換成JSON格式的字符串的過程,就叫做 JSON序列化

為什么需要?
當你的Spring Boot應用需要將數據顯示給前端(比如Web頁面、移動App)或者發送給其他服務時,你需要將你的Java對象(比如一個表示用戶的 User 對象,一個表示商品的 Product 對象)轉換成一種標準格式,以便接收方能夠理解。JSON就是最常用的標準格式之一。

想象一下:你的Java程序里有一個 Product 對象,它包含了 idnameprice 等屬性。你不能直接把這個Java對象“發送”出去。你需要把它包裝成一個字符串,這個字符串的格式就是JSON。

Java對象 (Product)  ───────>  JSON字符串
{ id: 1, name: "Laptop", price: 8000.0 }  ─序列化─>  '{"id":1,"name":"Laptop","price":8000.0}'

什么是 反序列化 (Deserialization)?

概念: 將一個JSON格式的字符串轉換成對應的Java對象的過程,就叫做 JSON反序列化

為什么需要?
當你的Spring Boot應用從前端(比如用戶提交的表單數據、通過API接收到的請求體)或其他服務接收到數據時,這些數據通常是JSON格式的字符串。為了在你的Java程序中處理這些數據,你需要將這些JSON字符串轉換成你可以操作的Java對象。

想象一下:前端通過一個表單提交了一個新商品的信息,數據以JSON字符串的形式發送到你的Spring Boot后端。你需要把這個JSON字符串轉換回一個 Product Java對象,這樣你才能方便地訪問 nameprice 等屬性,并進行業務邏輯處理(比如保存到數據庫)。

JSON字符串  ───────>  Java對象
'{"name":"Keyboard","price":300.0}'  ─反序列化─>  Java對象 (Product: { name: "Keyboard", price: 300.0 })

Spring Boot 如何實現 JSON 序列化和反序列化?

這是Spring Boot的強大之處:它自動化地處理了大部分情況下的JSON序列化和反序列化!

核心依賴:

在你的pom.xml文件中,如果你使用了spring-boot-starter-web這個依賴,那么你就已經自動引入了處理JSON所需的所有庫。

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

spring-boot-starter-web 依賴會間接地引入 spring-boot-starter-json 依賴,而 spring-boot-starter-json 默認使用的是 Jackson 這個庫來處理JSON。

Jackson 庫:

Jackson 是一個非常流行和強大的Java庫,專門用于處理JSON。Spring Boot通過自動配置,將Jackson設置為默認的 HttpMessageConverter

HttpMessageConverter 是 Spring MVC 中的一個核心概念,它負責將HTTP請求體轉換成Java對象(反序列化),以及將Java對象轉換成HTTP響應體(序列化)。當Spring Boot檢測到請求或響應涉及JSON時,它就會使用配置好的Jackson HttpMessageConverter 來完成轉換。

自動化體現在哪里?

在你編寫Spring Boot的Controller時,只需要使用特定的注解:

  1. 反序列化 (@RequestBody): 當你的Controller方法的參數前面加上 @RequestBody 注解時,Spring Boot會自動嘗試將HTTP請求體中的JSON字符串反序列化成這個參數對應的Java對象。
  2. 序列化 (@ResponseBody@RestController):
    • 如果你的Controller類使用了 @RestController 注解(它是 @Controller@ResponseBody 的組合),或者你的方法使用了 @ResponseBody 注解,Spring Boot會自動嘗試將方法的返回值序列化成JSON字符串,并作為HTTP響應體發送出去。

簡單來說,Spring Boot + Jackson 讓你在大多數情況下,只需要關注你的Java對象和Controller方法,而不需要手動編寫JSON解析和生成的代碼。

學習 JSON 序列化和反序列化有什么用?

對于新手來說,學習這個概念以及Spring Boot如何處理它,至少有以下幾個重要的用途:

  1. 理解 Web API 工作原理: 現代Web應用絕大多數都使用JSON進行前后端數據交互。理解序列化/反序列化是理解Spring Boot如何構建和響應API請求的基礎。你知道為什么你返回一個Java對象,前端卻收到了JSON數據;你知道為什么前端發送JSON數據,你卻可以直接在方法參數中拿到一個Java對象。
  2. 開發 RESTful API: Spring Boot是構建RESTful API的強大框架。RESTful API的核心就是通過HTTP請求(GET, POST, PUT, DELETE等)和JSON數據進行資源的交互。掌握JSON處理是開發API的必備技能。
  3. 數據交換和集成: 除了前后端,不同的微服務之間、你的服務和其他第三方服務之間也經常使用JSON交換數據。理解如何處理JSON是進行系統集成和數據交換的基礎。
  4. 調試和排錯: 當API調用失敗時,你可能會看到JSON解析或生成相關的錯誤(比如 HttpMessageNotReadableException 反序列化失敗,或者序列化結果不符合預期)。理解底層機制可以幫助你更快地定位和解決問題。
  5. 定制化需求: 雖然Spring Boot自動化處理了很多,但有時你需要更精細地控制JSON的輸出格式(比如日期格式、忽略某些字段、改變字段名等)。這時你需要了解Jackson提供的注解,而這些注解是基于序列化/反序列化的概念工作的。
  6. 數據存儲和配置文件: 有些應用會將數據以JSON格式存儲(比如NoSQL數據庫的一些場景),或者使用JSON作為配置文件格式。了解JSON處理有助于你讀寫這些數據。

實踐示例 (Spring Boot 項目)

我們通過一個簡單的例子來演示。

1. Maven 依賴 (確保 spring-boot-starter-webpom.xml 中):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.5</version> <!-- 使用你項目的實際版本 --><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>json-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>json-demo</name><description>Demo project for JSON serialization/deserialization</description><properties><java.version>17</java.version> <!-- 使用你的Java版本 --></properties><dependencies><!-- 這個依賴會自動引入 spring-boot-starter-json (包含 Jackson) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot 測試依賴 (可選) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2. 創建一個簡單的 Java 對象 (POJO):

這個對象將用于表示我們要在Java代碼中操作的數據結構。Jackson在進行反序列化時,默認會尋找無參構造函數,以及通過getter/setter方法來匹配JSON字段和對象屬性。為了簡化,我們使用Lombok庫來自動生成構造函數、getter/setter等。如果你不用Lombok,需要手動添加。

// Product.java
package com.example.jsondemo.model;import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;@Data // 自動生成 getter, setter, toString, equals, hashCode
@NoArgsConstructor // 自動生成無參構造函數 (反序列化需要)
@AllArgsConstructor // 自動生成全參構造函數 (可選,方便創建對象)
public class Product {private Long id;private String name;private double price;// 如果不用 Lombok,你需要手動添加:// public Product() {} // 無參構造函數// public Product(Long id, String name, double price) { ... } // 全參構造函數// public Long getId() { ... }// public void setId(Long id) { ... }// public String getName() { ... }// public void setName(String name) { ... }// public double getPrice() { ... }// public void setPrice(double price) { ... }
}

注意:如果你沒有使用Lombok,需要手動添加Lombok的Maven依賴并在IDE中安裝Lombok插件。或者手動寫出構造函數和getter/setter方法。

3. 創建一個 Spring Boot Controller:

這個Controller將演示如何接收JSON數據(反序列化)和返回JSON數據(序列化)。

// ProductController.java
package com.example.jsondemo.controller;import com.example.jsondemo.model.Product;
import org.springframework.web.bind.annotation.*;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;@RestController // @RestController 包含了 @Controller 和 @ResponseBody
@RequestMapping("/api/products")
public class ProductController {// 模擬一個存儲商品的列表 (實際應用中通常是數據庫)private List<Product> productList = new ArrayList<>();// 用于生成唯一的IDprivate AtomicLong nextId = new AtomicLong(1);// === 演示 JSON 反序列化 ===// 這個方法接收一個 POST 請求,請求體是 JSON 格式的 Product 對象@PostMappingpublic String createProduct(@RequestBody Product product) {// @RequestBody: Spring Boot (通過 Jackson) 會自動把請求體中的 JSON 字符串// 反序列化成一個 Product Java 對象,并賦值給 product 參數。System.out.println("接收到產品信息:");System.out.println("Name: " + product.getName());System.out.println("Price: " + product.getPrice());// 模擬保存商品并賦予IDproduct.setId(nextId.getAndIncrement());productList.add(product);// 返回一個簡單的字符串作為響應return "產品已創建,ID為: " + product.getId();}// === 演示 JSON 序列化 ===// 這個方法接收一個 GET 請求,并返回一個 Product 對象@GetMapping("/{id}")public Product getProductById(@PathVariable Long id) {// Spring Boot (通過 Jackson) 會自動把返回的 Product Java 對象// 序列化成 JSON 字符串,作為響應體發送出去。// 模擬從列表中查找商品 (實際應用中是查詢數據庫)for (Product product : productList) {if (product.getId().equals(id)) {System.out.println("正在返回產品信息 (將序列化為JSON): " + product);return product; // 返回 Java 對象}}// 如果找不到,返回 null (默認情況下 Jackson 會序列化為 'null')// 更健壯的做法是拋出異常或返回 ResponseEntity<Product> with status 404System.out.println("未找到ID為 " + id + " 的產品");return null;}// 演示返回一個列表的序列化@GetMappingpublic List<Product> getAllProducts() {// Spring Boot (通過 Jackson) 會自動把返回的 List<Product> 對象// 序列化成 JSON 數組,作為響應體發送出去。System.out.println("正在返回所有產品列表 (將序列化為JSON數組)");return productList;}
}

如何測試:

  1. 啟動你的Spring Boot應用。

  2. 使用工具(如 Postman, cURL, Insomnia)進行測試:

    • 測試反序列化 (POST請求):

      • URL: http://localhost:8080/api/products (如果你的應用運行在默認端口8080)

      • Method: POST

      • Headers: Content-Type: application/json

      • Body: 選擇 raw 并選擇 JSON,輸入以下JSON:

        {"name": "Wireless Mouse","price": 25.50
        }
        
      • 發送請求。你應該在控制臺看到打印的接收信息,并收到一個包含新產品ID的響應。

    • 測試序列化 (GET請求):

      • 假設上一步創建的產品ID是1。

      • URL: http://localhost:8080/api/products/1

      • Method: GET

      • 發送請求。你應該收到一個包含該產品信息的JSON響應,類似這樣:

        {"id": 1,"name": "Wireless Mouse","price": 25.5
        }
        
      • 測試返回列表 (GET請求):

        • URL: http://localhost:8080/api/products
        • Method: GET
        • 發送請求。你應該收到一個JSON數組,包含所有已創建的產品。

更進一步:Jackson 注解 (Customization)

雖然自動化很方便,但有時你需要控制JSON的輸出。Jackson提供了很多注解,可以在你的POJO類屬性或Getter/Setter方法上使用:

  • @JsonIgnore: 忽略某個屬性,不進行序列化和反序列化。
  • @JsonProperty("newFieldName"): 改變屬性在JSON中的字段名。
  • @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss"): 控制日期/時間字段的格式。
  • @JsonInclude(JsonInclude.Include.NON_NULL): 在序列化時,如果屬性值為null,則不包含該字段。
  • @JsonCreator, @JsonDeserialize, @JsonSerialize: 更高級的定制。

這些注解讓你能夠精細地調整Java對象和JSON之間的映射關系。

總結

  1. JSON 是一種常用的數據交換格式。
  2. 序列化 是將 Java 對象轉換為 JSON 字符串。
  3. 反序列化 是將 JSON 字符串轉換為 Java 對象。
  4. 在 Spring Boot 項目中,通過引入 spring-boot-starter-web (它包含了 Jackson 庫),Spring Boot 會自動配置 Jackson 作為默認的 HttpMessageConverter
  5. 你只需要在 Controller 方法中使用 @RequestBody (用于反序列化請求體) 和 @ResponseBody (或使用 @RestController,用于序列化返回值),Spring Boot 就會自動完成 JSON 的轉換工作。
  6. 學習這些有助于你理解和開發 Web API,進行數據交互,以及更好地調試應用。

希望這個詳細的解釋能幫助你這個新手更好地理解 Spring Boot 中的 JSON 處理!多動手實踐,你會越來越熟悉的。

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

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

相關文章

iOS/Android 使用 C++ 跨平臺模塊時的內存與生命周期管理

在移動應用開發領域,跨平臺開發已經成為一種不可忽視的趨勢。隨著智能手機市場的持續擴張,開發者需要同時滿足iOS和Android兩大主流平臺的需求,而這往往意味著重復的工作量和高昂的維護成本。跨平臺開發的目標在于通過一套代碼庫實現多平臺的支持,從而降低開發成本、加速產…

【AAudio】A2dp sink創建音頻軌道的源碼流程分析

一、AAudio概述 AAudio 是 Android 8.0(API 級別 26)引入的 C/C++ 原生音頻 API,專為需要低延遲、高性能音頻處理的應用設計,尤其適用于實時音頻應用(如音頻合成器、音樂制作工具、游戲音效等)。 1.1 主要特點 低延遲:通過減少音頻數據在內核與用戶空間之間的拷貝,直…

Spring中配置 Bean 的兩種方式:XML 配置 和 Java 配置類

在 Spring 框架中,配置 Bean 的方式主要有兩種:XML 配置 和 Java 配置類。這兩種方式都可以實現將對象注冊到 Spring 容器中,并通過依賴注入進行管理。本文將詳細介紹這兩種配置方式的步驟,并提供相應的代碼示例。 1. 使用 XML 配置的方式 步驟 創建 Spring 配置文件 創建…

海之淀攻略

家長要做的功課 家長可根據孩子情況&#xff0c;需要做好以下功課&#xff1a; 未讀小學的家長&#xff1a;了解小學小升初派位初中校額到校在讀小學的家長&#xff1a;了解小升初派位初中校額到校在讀初中的家長&#xff1a;了解初中校額到校 越是高年級的家長&#xff0c;…

BUUCTF-[GWCTF 2019]re3

[GWCTF 2019]re3 查殼&#xff0c;64位無殼 然后進去發現主函數也比較簡單&#xff0c;主要是一個長度校驗&#xff0c;然后有一個mprotect函數&#xff0c;說明應該又是Smc&#xff0c;然后我們用腳本還原sub_402219函數處的代碼 import idc addr0x00402219 size224 for …

sql server 開啟cdc報事務正在執行

今天開啟數據庫cdc 功能的時候提示&#xff1a;一個dbrole 的存儲過程&#xff0c;rolemember cdc db_ower, &#xff0c;有事務正在進行&#xff0c;執行失敗。 執行多次仍然如此&#xff0c;開啟cdc的存儲過程是sys.sp_cdc_enable_db;查詢了一下網絡&#xff0c;給出的方…

2025年GPLT團體程序設計天梯賽L1-L2

目錄 1.珍惜生命 2.偷感好重 3.高溫補貼 4.零頭就抹了吧 5.這是字符串題 6.這不是字符串題 7.大冪數?編輯 8.現代戰爭?編輯 9.算式拆解 10.三點共線 11.胖達的山頭 12.被n整除的n位數 1.珍惜生命 【解析】直接輸出即可 #include<bits/stdc.h> using namespace…

promethus基礎

1.下載prometheus并解壓 主要配置prometheus.yml文件 在scrape_configs配置項下添加配置(hadoop202是主機名)&#xff1a; scrape_configs: job_name: ‘prometheus’ static_configs: targets: [‘hadoop202:9090’] 添加 PushGateway 監控配置 job_name: ‘pushgateway’…

緩存與數據庫數據一致性:旁路緩存、讀寫穿透和異步寫入模式解析

旁路緩存模式、讀寫穿透模式和異步緩存寫入模式是三種常見的緩存使用模式&#xff0c;以下是對三種經典緩存使用模式在緩存與數據庫數據一致性方面更全面的分析&#xff1a; 一、旁路緩存模式&#xff08;Cache - Aside Pattern&#xff09; 1.數據讀取流程 應用程序首先向緩…

【ESP32S3】 下載時遇到 libusb_open() failed 解決方案

之前寫過一篇 《VSCode 開發環境搭建》 的文章&#xff0c;很多小伙伴反饋說在下載固件或者配置的時候會報錯&#xff0c;提示大多是 libusb_open() failed ...... &#xff1a; 這其實是由于 USB 驅動不正確導致的&#xff0c;準確來說應該是與 ESP-IDF 中內置的 OpenOCD 需要…

ISCTF2024-misc(部分)

前言 之前寫的&#xff0c;一直沒發&#xff0c;留個記錄吧&#xff0c;萬一哪天記錄掉了起碼在csdn有個念想 1.少女的秘密花園 打開是個圖片 隨波逐流binwalk一下分離得到一個zip&#xff0c;解壓得到base_misc發現是zip 爆破得到密碼 解壓得到一個txt&#xff0c;將里面的…

word內容使用python替換

擁有一個固定的word文件&#xff0c;類似模板 比如寫一個測試計劃&#xff0c;大多數內容都是通用&#xff0c;只需要改改軟件名稱&#xff0c;人員等等&#xff0c;數量多起來的情況下就可以使用代碼 # 導入 Document 類&#xff0c;用于處理 Word 文檔 from docx import Do…

py語法基礎理解

條件判斷 只有if-else等我語句,Python不支持switch語句 單if語句 if 條件語句: 條件為真時執行的內容 if-else語句 if 條件語句: 條件為真時執行的內容 else: 條件為假時執行的內容 if-elif語句 else if if 條件語句1: 條件語句1為真時執行的內容 elif 條件語句…

SQL進階知識:九、高級數據類型

今天介紹下關于高級數據類型的詳細介紹&#xff0c;并結合MySQL數據庫提供實際例子。 在MySQL中&#xff0c;高級數據類型主要用于處理復雜的數據結構&#xff0c;如JSON、XML和空間數據。這些數據類型提供了更強大的功能&#xff0c;可以滿足現代應用程序對數據存儲和處理的多…

Linux軟硬鏈接和動靜態庫(20)

文章目錄 前言一、軟硬鏈接基本認知實現原理應用場景取消鏈接ACM時間 二、動靜態庫認識庫庫的作用 三、制作靜態庫靜態庫的打包靜態庫的使用 四、制作動態庫動態區的打包動態庫的鏈接與使用動態庫的鏈接原理 總結 前言 我有款非常喜歡玩的游戲&#xff0c;叫做《饑荒》&#xf…

【鴻蒙HarmonyOS】深入理解router與Navigation

5. 路由 1.頁面路由(router模式&#xff09; 1.概述 頁面路由指的是在應用程序中實現不同頁面之間的跳轉&#xff0c;以及數據傳遞。 我們先明確自定義組件和頁面的關系&#xff1a; 自定義組件&#xff1a;Component 裝飾的UI單元&#xff0c;頁面&#xff1a;即應用的UI…

Apache SeaTunnel:新一代開源、高性能數據集成工具

Apache SeaTunnel 是一款開源、分布式、高性能的數據集成工具&#xff0c;可以通過配置快速搭建數據管道&#xff0c;支持實時海量數據同步。 Apache SeaTunnel 專注于數據集成和數據同步&#xff0c;主要旨在解決數據集成領域的常見問題&#xff1a; 數據源多樣性&#xff1a…

CF-Hero:自動繞過CDN找真實ip地址

CF-Hero&#xff1a;自動繞過CDN找真實ip地址 CF-Hero 是一個全面的偵察工具&#xff0c;用于發現受 Cloudflare 保護的 Web 應用程序的真實 IP 地址。它通過各種方法執行多源情報收集。目前僅支持Cloudflare的cdn服務查找真實ip&#xff0c;但從原理上來說查找方法都是通用的…

React-組件和props

1、類組件 import React from react; class ClassApp extends React.Component {constructor(props) {super(props);this.state{};}render() {return (<div><h1>這是一個類組件</h1><p>接收父組件傳過來的值&#xff1a;{this.props.name}</p>&…

談談接口和抽象類有什么區別?

接口&#xff08;interface&#xff09;和抽象類&#xff08;abstract class&#xff09;都是 Java 中常用的“抽象”工具&#xff0c;用來定義類的規范和結構&#xff0c;但它們有一些本質的區別。下面我用一個簡單明了的表格 說明來幫你理解&#xff1a; 對比點抽象類&…