JSON(JavaScript对象表示法)是一组键-值对,可以被应用程序轻松解析和生成。它是 JavaScript 编程语言标准 ECMA-262 的一个子集。大多数应用程序都需要解析 JSON,比如 restful APIs 或需要数据序列化的应用程序。
在 Java 生态系统中,处理 JSON 数据的两个最流行的库是 Jackson 和 Gson。两者都被广泛使用并提供独特的优势。本文使用边缘案例示例来探索这两个库在不同参数上的特性。
Jackson 和 Gson 简要概述
Jackson
Jackson由 FasterXML 开发,被用于企业应用程序和诸如 Spring Boot 等框架。它提供 JSON 数据的解析、序列化和反序列化。以下特性使得该库在开发人员中广受欢迎:
- Jackson 是 Spring Boot 中的默认 JSON 处理库,在大多数情况下消除了手动配置。
- 它通过 TypeReference 或 JavaType 实现 JSON 反序列化为通用类型。
- 它提供不同的注解来自定义序列化和反序列化行为。例如,
@JsonProperty(name)
可以使传入键和实际 Java POJO 字段之间的映射无缝连接。 - 它支援廣泛且強大的雙向數據綁定(JSON 轉 POJO 及反向操作),流 API(API 將 JSON 讀入 POJO),以及樹模型解析(一個 JSON 對象的內存映射)。
- Jackson 庫由於最小化內存開銷並優化序列化/反序列化(從 JSON 到 POJO 及反向操作),因此具有高性能。
- Jackson 支援其他模組,如 XML、YAML 處理,以及 Kotlin、scala 特定增強功能。
- 諸如
@JsonTypeInfo
和@JsonSubTypes
之類的註釋處理多態類型。 - 由於其向後和向前兼容性,它可以處理 JSON 數據中缺失或額外的字段。
- Jackson 支援不可變對象和具有構造函數的類,包括使用生成器模式的類。
ObjectMapper
類是線程安全的,因此可在多線程應用程序中高效使用。
Gson
Gson是由 Google 開發的,旨在將 JSON 轉換為 Java 對象(POJO)及反向操作。它簡單且適用於需要快速實現的小型應用程序。這個開源庫提供以下主要功能:
- Gson 具有最小的外部依賴,因此易於集成。
- 它支援嵌套物件和複雜的資料類型,如列表、映射和自定義類。
- 它可以將JSON反序列化為通用集合,如
List<T>
、Map<K,V>
,使用TypeToken。 - Gson Library的JsonSerializer和JsonDeserializer接口允許自定義實現。
- 默認情況下,在JSON輸出中排除空值,如果需要,可以將空值包含在輸出中。
- 註釋
@SerializedName
將JSON鍵映射到具有不同名稱的Java字段。 - Gson對象是線程安全的,因此可以在多線程應用程序中使用。
- Class GsonBuilder可以為字段應用自定義命名策略。例如,
FieldNamingPolicy.IDENTITY
是默認策略,表示字段名稱不變。
在此比較中考慮的特殊情況
Feature | Jackson | GSON |
---|---|---|
額外字段 |
默認情況下被忽略,可配置。 |
默認情況下被忽略。 |
空值 |
支援@JsonInclude。 |
需要使用.serializeNulls()。 |
循環引用 |
使用@JsonIdentityInfo支持。 |
不直接支持。 |
數據處理 |
支持Java 8日期API並帶有模塊。 |
需要自定義類型適配器。 |
多態 |
內建@JsonTypeInfo。 |
需要自定義反序列化邏輯。 |
考慮與Jackson和Gson庫進行比較的輸入JSON位於GitHub上。
JSON的模型類表示位於GitHub上。
Jackson實現
上述JSON使用以下Jackson庫轉換為Java對象:
<!-- Jackson START-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.2</version>
</dependency>
<!-- Jackson END-->
Jackson庫的JSON解析main類:
public class JacksonJsonMain {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
//Jackson Support for LocalDate using jackson-datatype-jsr310
mapper.registerModule(new JavaTimeModule());
//Configuration to ignore extra fields
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Deserialize the JSON
EmployeeModelData employeeModelData = mapper.readValue(json, EmployeeModelData.class);
Employee employee=employeeModelData.getEmployee();
// display Json fields
System.out.println("Jackson Library parsing output");
System.out.println("Employee Name: " + employee.getName());
System.out.println("Department Name: " + employee.getDepartment().getName());
System.out.println("Skills: " + employee.getSkills());
System.out.println("Team Members Count: " + employeeModelData.getTeamMembers().size());
}
}
上述類的輸出如下:
Gson實現
將上述JSON轉換為Java對象所使用的Gson依賴如下:
<!--GSON START -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!--GSON END -->
使用GSON庫進行JSON解析的main類:
public class GsonJsonMain {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // Register LocalDate adapter
.serializeNulls() // Handle null values
.setPrettyPrinting() // Pretty print JSON
.create();
// Deserialize the JSON
EmployeeModelData data = gson.fromJson(json, EmployeeModelData.class);
// Print Employee information
System.out.println("GSON Library parsing output");
System.out.println("Employee Name: " + data.getEmployee().getName());
System.out.println("Department Name: " + data.getEmployee().getDepartment().getName());
System.out.println("Skills: " + data.getEmployee().getSkills());
System.out.println("Team Members Count: " + data.getTeamMembers().size());
}
}
上述主類的輸出如下:
我應該選擇哪一個?
Jackson提供高性能;因此,在項目涉及復雜數據結構或大數據集時必須使用它,而在存在較小數據集且數據結構簡單時,必須使用Gson。
結論
這兩個庫都可以有效地處理上述數據集,在JAVA中處理JSON解析時表現出色。上述比較有助於根據項目需求選擇合適的庫。
上述代碼片段可在GitHub存儲庫中找到。
有關Jackson和Gson的詳細比較可在Baeldung上找到。Jackson官方文檔提供了有關Jackson功能和配置的詳細信息。同樣,Gson官方文檔提供了詳細的實施指南。
Source:
https://dzone.com/articles/jackson-vs-gson-edge-cases-json-parsing-java