前言
JSON 作為現代應用的標準數據交換格式,Java 生態提供了豐富的處理庫。本文對比三大主流方案:Gson(Google)、Jackson(企業級標準)、org.json(輕量原生),涵蓋解析、生成、流式處理、樹模型、數據綁定全場景。
一、Gson:簡潔優雅的對象綁定
1.1 依賴引入
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
1.2 核心 API:JsonParser、JsonObject、JsonArray
// 解析 JSON 字符串/文件
String json = "{ \"cat\":\"it\", \"languages\":[{\"id\":1,\"ide\":\"Eclipse\",\"name\":\"Java\"}], \"pop\":true }";
JsonParser parser = new JsonParser();
JsonObject root = parser.parse(json).getAsJsonObject();
// 提取值
String cat = root.get("cat").getAsString();
boolean pop = root.get("pop").getAsBoolean();
// 遍歷數組
JsonArray languages = root.getAsJsonArray("languages");
for (JsonElement elem : languages) {
JsonObject lang = elem.getAsJsonObject();
int id = lang.get("id").getAsInt();
String ide = lang.get("ide").getAsString();
String name = lang.get("name").getAsString();
System.out.printf("ID:%d IDE:%s Name:%s%n", id, ide, name);
}
1.3 生成 JSON
JsonObject root = new JsonObject();
root.addProperty("cat", "it");
JsonArray languages = new JsonArray();
IntStream.of(1,2,3).forEach(id -> {
JsonObject lang = new JsonObject();
lang.addProperty("id", id);
lang.addProperty("ide", switch(id){case 1->"Eclipse";case 2->"XCode";default->"VS Code"});
lang.addProperty("name", switch(id){case 1->"Java";case 2->"Swift";default->"TypeScript"});
languages.add(lang);
});
root.add("languages", languages);
root.addProperty("pop", true);
String output = new GsonBuilder().setPrettyPrinting().create().toJson(root);
// 或 root.toString() 緊湊格式
1.4 對象綁定(Data Binding)
// 定義 POJO
@Data class Language { int id; String ide; String name; }
@Data class Catalog { String cat; List<Language> languages; boolean pop; }
// 反序列化
Catalog catalog = new Gson().fromJson(json, Catalog.class);
// 序列化
String jsonOut = new Gson().toJson(catalog);
二、Jackson:高性能企業級標準
2.1 依賴(Spring Boot 已內置)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
2.2 三大處理模式
| 模式 | 核心類 | 特點 | 適用場景 |
| 樹模型 | ObjectMapper、JsonNode | 隨機訪問、結構靈活 | 結構不固定、需動態修改 JSON |
| 流式 API | JsonParser、JsonGenerator | 低內存、高性能、單向流 | 大文件、高吞吐、嵌入式環境 |
| 數據綁定 | ObjectMapper.readValue/writeValue | POJO 直轉、開發效率最高 | 常規業務開發、REST API |
2.3 實戰代碼
ObjectMapper mapper = new ObjectMapper()
.configure(SerializationFeature.INDENT_OUTPUT, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(new JavaTimeModule()); // 支援 LocalDateTime
// 1. 數據綁定(最常用)
Catalog catalog = mapper.readValue(jsonString, Catalog.class);
String json = mapper.writeValueAsString(catalog);
// 2. 樹模型動態處理
JsonNode root = mapper.readTree(jsonString);
String cat = root.get("cat").asText();
((ObjectNode)root).put("newField", "value");
root.get("languages").forEach(node -> System.out.println(node.get("name")));
// 3. 流式解析大文件
try (JsonParser parser = mapper.getFactory().createParser(new File("big.json"))) {
while (parser.nextToken() != JsonToken.END_ARRAY) {
if (parser.currentToken() == JsonToken.START_OBJECT) {
Language lang = mapper.readValue(parser, Language.class);
process(lang);
}
}
}
2.4 進階配置
// 忽略 NULL 字段
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 日期格式統一
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 多態反序列化
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL);
三、org.json:零依賴輕量選擇
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
JSONObject obj = new JSONObject();
obj.put("name", "張三");
obj.put("age", 25);
JSONArray arr = new JSONArray();
arr.put(new JSONObject().put("k", "v"));
String json = obj.toString(); // 緊湊格式
String pretty = obj.toString(4); // 縮進 4 空格
// 解析
JSONObject parsed = new JSONObject(jsonString);
String name = parsed.getString("name");
四、性能與選型建議
| 維度 | Gson | Jackson | org.json |
| 序列化性能 | 優 | 極優(後端熱路徑首選) | 中 |
| 反序列化性能 | 優 | 極優 | 中 |
| 內存佔用 | 中 | 低(流式最低) | 高 |
| API 易用性 | 最高 | 高 | 高 |
| 功能豐富度 | 中 | 最高(模塊化擴展) | 基礎 |
| Spring Boot 整合 | 需排除 Jackson | 默認內置 | 手動引入 |
五、最佳實踐總結
- Spring Boot 項目:直接使用內置 Jackson,配置
ObjectMapper Bean 統一風格
- Android/獨立項目:Gson 體積小、API 直觀、Kotlin 適配好
- 大文件/高吞吐:Jackson 流式 API(
JsonParser/JsonGenerator)
- 動態結構/腳本交互:Jackson 樹模型(
JsonNode)
- 零依賴/簡單場景:org.json 足夠
- 避坑指南:
- 日期類型統一用
JavaTimeModule(Jackson)或 LocalDateTimeAdapter(Gson)
- 循環引用:
@JsonIgnore / @Expose / @JsonManagedReference
- 多態反序列化需啟用 TypeInfo
- 數字精度:大數用
BigDecimal,避免 Double 精度丟失