解析JSON的這六種方法,真香!
前言
在 Java 開發中,解析 JSON 是一個非常常見的需求。
不管是和前端交互、調用第三方接口,還是處理配置文件,幾乎都繞不開 JSON。
這篇文章總結了6種主流的 JSON 解析方法,希望對你會有所幫助。
1. 使用 Jackson:業界標配
功能特點
- 強大的序列化和反序列化:支持將 JSON 字符串轉為 Java 對象,也支持將 Java 對象轉換為 JSON。
- 支持復雜結構:處理嵌套對象、數組、泛型等場景非常輕松。
- 支持注解:如 @JsonIgnore、@JsonProperty 等,能精細控制序列化與反序列化的行為。
- 性能高:Jackson 的性能非常出色,是很多企業級項目的首選。
代碼示例
- JSON 轉對象(反序列化)
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonExample {
public static void main(String[] args) throws Exception {
String json = "{\"id\":1,\"name\":\"張三\"}";
ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(json, User.class);
System.out.println(user.getName()); // 輸出:張三
}
}
class User {
private int id;
private String name;
// Getters 和 Setters 省略
}
- 對象轉 JSON(序列化)
User user = new User();
user.setId(1);
user.setName("李四");
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(user);
System.out.println(json); // 輸出:{"id":1,"name":"李四"}
高級功能
- 日期格式化:@JsonFormat(pattern = "yyyy-MM-dd")
- 忽略字段:@JsonIgnore
- 重命名字段:@JsonProperty("custom_name")
優缺點
優點 | 缺點 |
功能全面,支持復雜場景 | 配置較多,學習成本稍高 |
性能高,社區活躍,企業級項目首選 | 過于強大,部分功能用不上 |
豐富的注解支持,便于控制序列化行為 | 庫體積較大,對于小型項目略顯笨重 |
2. 使用 Gson:輕量好用
功能特點
- 輕量級:Gson 的設計非常簡潔,代碼量少,適合中小型項目。
- 支持泛型:可以輕松解析帶泛型的 JSON。
- 注解控制:支持通過注解控制序列化行為,如 @Expose。
- 易擴展:通過自定義序列化器和反序列化器,可以處理復雜的場景。
代碼示例
- JSON 轉對象
import com.google.gson.Gson;
public class GsonExample {
public static void main(String[] args) {
String json = "{\"id\":1,\"name\":\"王五\"}";
Gson gson = new Gson();
User user = gson.fromJson(json, User.class);
System.out.println(user.getName()); // 輸出:王五
}
}
- 對象轉 JSON
User user = new User();
user.setId(2);
user.setName("趙六");
Gson gson = new Gson();
String json = gson.toJson(user);
System.out.println(json); // 輸出:{"id":2,"name":"趙六"}
高級功能
- 忽略字段:@Expose
@Expose
private String name;
- 自定義序列化器/反序列化器:
Gson gson = new GsonBuilder()
.registerTypeAdapter(CustomClass.class, new CustomSerializer())
.create();
優缺點
優點 | 缺點 |
輕量級,簡單易用,適合中小型項目 | 性能稍遜于 Jackson |
學習曲線平滑,新手容易上手 | 功能不如 Jackson 豐富 |
提供良好的擴展能力 | 復雜對象處理起來較為麻煩 |
3. 使用 FastJSON:高性能
功能特點
- 性能優異:FastJSON 的解析速度非常快,適合大數據量場景。
- 支持動態字段:可以輕松處理動態 JSON 數據。
- 強大的類型支持:支持嵌套對象、泛型、數組等復雜結構。
- 注解控制:類似 Jackson 和 Gson,支持注解控制字段的序列化和反序列化。
代碼示例
- JSON 轉對象
import com.alibaba.fastjson.JSON;
public class FastJsonExample {
public static void main(String[] args) {
String json = "{\"id\":1,\"name\":\"小明\"}";
User user = JSON.parseObject(json, User.class);
System.out.println(user.getName()); // 輸出:小明
}
}
- 對象轉 JSON
User user = new User();
user.setId(3);
user.setName("小紅");
String json = JSON.toJSONString(user);
System.out.println(json); // 輸出:{"id":3,"name":"小紅"}
高級功能
- 自動駝峰轉下劃線:
JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
- 動態字段解析:
Map<String, Object> map = JSON.parseObject(json, Map.class);
優缺點
優點 | 缺點 |
性能極高,解析速度快 | 曾有歷史安全漏洞的爭議 |
支持復雜的動態字段解析 | 社區活躍度稍遜于 Jackson 和 Gson |
功能全面,適合大規模數據處理場景 | 配置選項和 API 比較多,稍顯復雜 |
4. 使用 JsonPath:快速提取嵌套字段
功能特點
- 高效字段提取:通過路徑表達式(類似 XPath)快速提取嵌套字段。
- 靈活性強:支持動態字段和條件過濾。
- 輕量級:專注于字段提取,功能簡單明確。
代碼示例
import com.jayway.jsonpath.JsonPath;
public class JsonPathExample {
public static void main(String[] args) {
String json = """
{
"store": {
"book": [
{"title": "書1", "price": 10},
{"title": "書2", "price": 20}
]
}
}
""";
// 提取第一個書籍的標題
String title = JsonPath.read(json, "$.store.book[0].title");
System.out.println(title); // 輸出:書1
// 提取所有書籍價格
List<Integer> prices = JsonPath.read(json, "$.store.book[*].price");
System.out.println(prices); // 輸出:[10, 20]
}
}
優缺點
優點 | 缺點 |
字段提取簡潔高效 | 不支持序列化和反序列化 |
動態字段處理能力強 | 依賴 JsonPath 語法 |
適合快速提取嵌套字段 | 不適合全量 JSON 轉換 |
5. 使用 org.json:輕量工具類
功能特點
- 輕量級:核心是一個工具類,適合簡單場景。
- 構造和解析簡單:適合快速創建 JSON 或提取字段。
- 靈活性一般:不支持復雜對象映射。
代碼示例
import org.json.JSONObject;
public class OrgJsonExample {
public static void main(String[] args) {
String json = "{\"id\":1,\"name\":\"張三\"}";
// 提取字段
JSONObject jsonObject = new JSONObject(json);
System.out.println(jsonObject.getString("name")); // 輸出:張三
// 構造 JSON
JSONObject newJson = new JSONObject();
newJson.put("id", 2);
newJson.put("name", "李四");
System.out.println(newJson.toString()); // 輸出:{"id":2,"name":"李四"}
}
}
優缺點
優點 | 缺點 |
輕量級,適合簡單場景 | 不支持復雜嵌套對象 |
使用簡單,學習成本低 | 功能簡單,擴展性差 |
6. 手動解析 JSON:靈活度最高
功能特點
- 完全自由:不依賴第三方庫,自己解析 JSON。
- 動態處理:適合不規則字段結構的 JSON。
- 代碼復雜度高:適合特殊場景。
代碼示例
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class ManualParsing {
public static void main(String[] args) throws Exception {
String json = "{\"id\":1,\"name\":\"動態字段\"}";
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});
System.out.println(map.get("name")); // 輸出:動態字段
}
}
優缺點
優點 | 缺點 |
靈活性高,適合動態字段 | 代碼復雜度高,不易維護 |
不依賴第三方庫 | 性能和效率低于專業 JSON 庫 |
總結
最后給大家對比一下文章中提到的6種方法各自的優缺點:
方法 | 適用場景 | 優點 | 缺點 |
Jackson | 企業級項目,復雜序列化和反序列化場景 | 功能強大,性能優異,支持復雜結構 | 配置復雜,學習曲線高 |
Gson | 中小型項目,簡單的 JSON 轉換場景 | 輕量級,簡單易用 | 功能有限,性能略遜 |
FastJSON | 高性能需求,大數據量的動態解析 | 性能極高,功能豐富 | 曾有安全漏洞爭議,社區支持稍遜 Jackson |
JsonPath | 嵌套結構復雜、動態字段提取場景 | 字段提取語法簡單,靈活性強 | 不支持序列化和反序列化 |
org.json | 快速解析或構造 JSON 場景 | 輕量級,適合簡單場景 | 功能單一,擴展性差 |
手動解析 | 動態 JSON 或字段不固定的場景 | 自由度高,靈活性強 | 代碼復雜,效率低于專業工具 |
工具千千萬,場景最重要!
選對了工具,才能省時省力,少踩坑多摸魚。