減少JSON數據大小

Jackson,JSON
Remote
0
09:54 PM · Nov 30 ,2025

1. 簡介

Java 應用程序經常使用 JSON 作為發送和接收數據的常用格式。它還被用作存儲數據的序列化協議。 隨着較小的 JSON 數據大小,我們的應用程序將更便宜、更快。

在本教程中,我們將探討在 Java 應用程序中減少 JSON 大小的各種方法。

2. 領域模型和測試數據

讓我們為 客户 創建一個領域模型,幷包含一些聯繫數據:

public class Customer {
    private long id;
    private String firstName;
    private String lastName;
    private String street;
    private String postalCode;
    private String city;
    private String state;
    private String phoneNumber;
    private String email;
}

請注意,所有字段都必須是必填項,除了 phoneNumberemail

為了正確測試 JSON 數據大小差異,我們需要至少幾百個 客户 實例。 它們必須具有不同的數據,使我們的測試更逼真。 數據生成網站 mockaroo 可以幫助我們。 我們可以在那裏免費創建 1,000 個 JSON 數據記錄,採用我們的格式,並使用真實的測試數據。

讓我們為我們的領域模型配置 mockaroo

JSON 生成

這裏有一些需要注意的事項:

  • 在這裏,我們指定了字段名稱
  • 在這裏,我們選擇了字段的數據類型
  • 50% 的電話號碼在模擬數據中為空
  • 30% 的電子郵件地址也為空

以下所有代碼示例都使用來自 mockaroo 的 1,000 個客户的數據。 我們使用工廠方法 Customer.fromMockFile() 來讀取該文件並將其轉換為 Customer 對象。

我們將使用 Jackson 作為我們的 JSON 處理庫。

3. JSON 數據大小與 Jackson 默認選項

讓我們用 Jackson 默認選項將 Java 對象寫入 JSON:

Customer[] customers = Customer.fromMockFile();
ObjectMapper mapper = new ObjectMapper();
byte[] feedback = mapper.writeValueAsBytes(customers); 

讓我們查看第一個 Customer 的模擬數據:

{
  "id" : 1, 
  "firstName" : "Horatius", 
  "lastName" : "Strognell", 
  "street" : "4848 New Castle Point", 
  "postalCode" : "33432", 
  "city" : "Boca Raton", 
  "state" : "FL", 
  "phoneNumber" : "561-824-9105", 
  "email" : "[email protected]"
}

使用默認 Jackson 選項時,包含所有 1,000 個客户的 JSON 數據字節數組大小為 181.0 KB

4. 使用 gzip 進行壓縮

作為文本數據,JSON 數據壓縮效果很好。因此,gzip 是我們首選的選項,用於減少 JSON 數據的大小。 此外,它可以在 HTTP 中自動應用,HTTP 是發送和接收 JSON 的常見協議。

讓我們以使用默認 Jackson 選項生成的 JSON 數據進行壓縮,並使用 gzip。 結果為 45.9 KB,僅佔原始大小的 25.3% 。 因此,如果我們通過配置啓用 gzip 壓縮,我們可以在不修改 Java 代碼的情況下將 JSON 數據大小減少 75%!

如果我們的 Spring Boot 應用程序將 JSON 數據傳遞給其他服務或前端,那麼我們將在 Spring Boot 配置中啓用 gzip 壓縮。 讓我們看一個典型的壓縮配置,使用 YAML 語法:

server:
  compression:
    enabled: true
    mime-types: text/html,text/plain,text/css,application/javascript,application/json
    min-response-size: 1024

首先,我們通過將 enabled 設置為 true 來啓用壓縮。 然後,我們通過將 application/json 添加到 mime-types 列表中來專門啓用 JSON 數據壓縮。 最後,請注意,我們設置了 min-response-size 為 1,024 字節。 這是因為如果壓縮少量數據,我們可能會產生比原始數據更大的數據。

通常,像 NGINX 這樣的代理或像 Apache HTTP Server 這樣的 Web 服務器會將 JSON 數據傳遞給其他服務或前端。 在這些工具中配置 JSON 數據壓縮超出了本教程的範圍。

一篇關於 gzip 的以前教程告訴我們,gzip 具有各種壓縮級別。 我們的代碼示例使用 gzip 與默認 Java 壓縮級別一起使用。 Spring Boot、代理或 Web 服務器可能會針對相同 JSON 數據產生不同的壓縮結果。

如果我們將 JSON 用作序列化協議來存儲數據,那麼我們需要自己壓縮和解壓縮數據。

5. 簡短的字段名稱在JSON中的使用

使用既不短也不長的字段名稱是一種最佳實踐。為了演示目的,我們暫時不這樣做:我們將使用單字符的字段名稱在JSON中,但不會更改Java字段名稱。這減少了JSON數據的大小,但降低了JSON的可讀性。由於這也會需要更新所有服務和前端,我們可能只會使用這些短字段名稱來存儲數據:


{
  "i" : 1,
  "f" : "Horatius",
  "l" : "Strognell",
  "s" : "4848 New Castle Point",
  "p" : "33432",
  "c" : "Boca Raton",
  "a" : "FL",
  "o" : "561-824-9105",
  "e" : "[email protected]"
}

使用Jackson可以輕鬆更改JSON字段名稱,同時保持Java字段名稱不變。我們將使用@JsonProperty註解:


@JsonProperty("p")
private String postalCode;

使用單字符字段名稱會導致數據大小減少72.5%,相對於原始數據減少23.8%。這比我們簡單地壓縮原始數據gzip得到的25.3%要小不了多少。我們始終需要尋找合適的成本效益關係。為了一個小的尺寸減少而犧牲可讀性,對於大多數場景來説是不值得推薦的。

6. 序列化為數組

讓我們看看如何通過完全省略字段名稱來進一步減少 JSON 數據的大小。我們可以通過將 customers 數組存儲在我們的 JSON 中來實現這一點。請注意,這也會降低可讀性。並且我們需要更新所有使用我們的 JSON 數據的服務和前端。

[ 1, "Horatius", "Strognell", "4848 New Castle Point", "33432", "Boca Raton", "FL", "561-824-9105", "[email protected]" ]

Customer 存儲為數組會導致輸出大小為原始大小的 53.1%,使用 gzip 壓縮後為 22.0%。這是我們目前取得的最佳結果。然而,22% 仍然小於我們從僅使用 gzip 壓縮原始數據獲得的 25.3%。

為了將客户序列化為數組,我們需要對 JSON 序列化進行完全控制。請再次參考我們的 Jackson 教程以獲取更多示例。

7. 排除 null

Jackson 和其他 JSON 處理庫在讀取或寫入 JSON 時,可能無法正確處理 JSON 中的 null 值。例如,Jackson 默認情況下會寫入 JSON 中的 null 值,當它遇到 Java 中的 null 值時。因此,建議在 JSON 數據中刪除空字段。這會將空值的初始化留給每個 JSON 處理庫,並減少 JSON 數據的大小。

在我們的模擬數據中,我們將 50% 的電話號碼和 30% 的電子郵件地址設置為為空。 排除這些 null 值將我們的 JSON 數據大小減少到 166.8KB 或原始數據大小的 92.1%。 然後,gzip 壓縮將將其減少到 24.9%。

現在,如果我們結合忽略 null 值與上一部分中更短的字段名稱,那麼我們將獲得更大的節省:原始大小的 68.3% 和使用 gzip 時 23.4%。

我們可以配置 Jackson 中排除 null 值字段的設置,按類或全局設置,應用於所有類。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.