首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 解析 JSON 字符串實戰:原生 JSONObject/JSONArray 與 Gson/Jackson 三大主流庫對比

     編輯:Java 綜合教學

Java 解析 JSON 字符串實戰:從 org.json 到 Gson/Jackson 全方位指南

JSON 是現代 Web 交互的標準格式。Java 生態中有三大主流解析庫:org.json (輕量、JDK 內置風格)、Gson (Google、對象綁定強)、Jackson (Spring Boot 默認、性能最優、功能最全)。本文通過實戰代碼對比三者核心用法,助你選型與避坑。

一、 核心數據模型對比

概念org.jsonGsonJackson
JSONObjectorg.json.JSONObjectcom.google.gson.JsonObjectcom.fasterxml.jackson.databind.JsonNode (ObjectNode)
JSONArrayorg.json.JSONArraycom.google.gson.JsonArraycom.fasterxml.jackson.databind.JsonNode (ArrayNode)
對象綁定手動 get/setgson.fromJson(json, User.class)mapper.readValue(json, User.class)
流式解析不支持JsonReader/JsonWriterJsonParser/JsonGenerator (核心優勢)
Maven 坐標org.json:json:20231013com.google.code.gson:gson:2.10.1com.fasterxml.jackson.core:jackson-databind:2.15.2

二、 解析 JSON 字符串到對象 (反序列化)

1. org.json 手動映射 (輕量、無依賴對象綁定)

// 依賴: org.json:json
String jsonStr = "{\"id\":1,\"name\":\"Tom\",\"age\":25,\"skills\":[\"Java\",\"Go\"]}";

public User parseWithOrgJson(String jsonStr) {
    try {
        JSONObject json = new JSONObject(jsonStr);
        User user = new User();
        user.setId(json.getLong("id"));
        user.setName(json.getString("name"));
        user.setAge(json.getInt("age"));
        
        // 解析數組
        JSONArray skillArr = json.getJSONArray("skills");
        List skills = new ArrayList<>();
        for (int i = 0; i < skillArr.length(); i++) {
            skills.add(skillArr.getString(i));
        }
        user.setSkills(skills);
        return user;
    } catch (JSONException e) {
        throw new RuntimeException("JSON 解析失敗", e);
    }
}

2. Gson 一行綁定 (推薦簡單場景)

// 依賴: com.google.code.gson:gson
Gson gson = new Gson(); // 線程安全,可復用單例

// 字符串 -> 對象
User user = gson.fromJson(jsonStr, User.class);

// 字符串 -> List
Type listType = new TypeToken>(){}.getType();
List users = gson.fromJson("[{\"id\":1},{\"id\":2}]", listType);

// 處理字段名不一致 (@SerializedName)
class User {
    @SerializedName("user_name") // JSON 字段 user_name -> Java 字段 name
    private String name;
}

3. Jackson 企業級標配 (Spring Boot 默認)

// 依賴: com.fasterxml.jackson.core:jackson-databind
ObjectMapper mapper = new ObjectMapper(); // 線程安全,全局單例

// 核心配置 (推薦全局配置一次)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略多餘字段
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); // 日期輸出 ISO-8601
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
mapper.registerModule(new JavaTimeModule()); // 支持 LocalDateTime 等 Java 8 時間類型

// 字符串 -> 對象
User user = mapper.readValue(jsonStr, User.class);

// 字符串 -> List
List users = mapper.readValue(jsonArrayStr, new TypeReference>() {});

// 處理字段名映射 (@JsonProperty)
class User {
    @JsonProperty("user_name")
    private String name;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
}

三、 對象轉 JSON 字符串 (序列化)

User user = new User(1L, "Tom", 25, Arrays.asList("Java", "Go"));

// org.json
JSONObject json = new JSONObject();
json.put("id", user.getId());
json.put("name", user.getName());
// ... 手動構建,繁瑣

// Gson
String jsonGson = gson.toJson(user); // {"id":1,"name":"Tom","age":25,"skills":["Java","Go"]}

// Jackson
String jsonJackson = mapper.writeValueAsString(user);
// 格式化輸出
String pretty = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);

四、 進階場景實戰

1. 解析嵌套 JSON / 動態結構 (無對應實體類)

// Jackson JsonNode 樹模型 (靈活、高性能)
JsonNode root = mapper.readTree(jsonStr);
Long id = root.path("id").asLong(); // path 安全獲取,無則返回 MissingNode
String name = root.path("name").asText();
JsonNode skillsNode = root.path("skills");
if (skillsNode.isArray()) {
    for (JsonNode skill : skillsNode) {
        System.out.println(skill.asText());
    }
}

// Gson JsonParser
JsonElement element = JsonParser.parseString(jsonStr);
JsonObject obj = element.getAsJsonObject();
JsonArray skills = obj.getAsJsonArray("skills");

2. 日期/時間類型處理 (避坑重點)

// Jackson (推薦 Java 8+ LocalDateTime)
mapper.registerModule(new JavaTimeModule()); // 必須註冊
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 標註字段

// Gson
Gson gson = new GsonBuilder()
    .registerTypeAdapter(LocalDateTime.class, new JsonSerializer() {
        @Override public JsonElement serialize(LocalDateTime src, Type type, JsonSerializationContext context) {
            return new JsonPrimitive(src.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
    })
    .create();

3. Null 值處理

// Gson: 默認不輸出 null 字段
// 輸出 null: new GsonBuilder().serializeNulls().create()

// Jackson: 默認輸出 null
// 忽略 null: mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
// 或類上: @JsonInclude(JsonInclude.Include.NON_NULL)

4. 大文件/流式解析 (內存友好)

// Jackson 流式 API (核心優勢:低內存、高性能)
try (JsonParser parser = mapper.getFactory().createParser(new File("huge.json"))) {
    while (parser.nextToken() != JsonToken.END_OBJECT) {
        if (parser.currentToken() == JsonToken.FIELD_NAME && "id".equals(parser.currentName())) {
            parser.nextToken(); // 移動到 VALUE
            long id = parser.getLongValue();
            // 處理 id...
        }
    }
}
// Gson 流式
try (JsonReader reader = new JsonReader(new FileReader("huge.json"))) {
    reader.beginObject();
    while (reader.hasNext()) { ... }
}

五、 選型建議與避坑清單

場景推薦庫理由
Spring Boot / 微服務 / 高性能 / 複雜映射Jackson生態完善、流式解析、模塊化擴展、Spring 生態原生
Android / 簡單對象綁定 / 無 Spring 環境GsonAPI 極簡、體積較小、適應性強
極簡依賴 / 無實體類動態解析 / 單文件工具類org.json單 jar 無依賴、API 直觀、Android 內置 (org.json 包)
大數據/日誌/流式處理Jackson Streaming API唯一成熟的流式解析器,內存常數級

避坑鐵律

  1. ObjectMapper / Gson 實例化一次,全局復用 (線程安全),避免重複創建開銷。
  2. 必須配置 `FAIL_ON_UNKNOWN_PROPERTIES = false`,否則新增字段導致反序列化崩潰。
  3. 日期類型統一用 Java 8 `LocalDateTime` + `JavaTimeModule` / `GsonTypeAdapter`,拒絕 `java.util.Date`/`long` timestamp 混用。
  4. 泛型集合反序列化必須用 `TypeReference` (Jackson) 或 `TypeToken` (Gson),擦除機制導致無法直接傳 `List.class`。
  5. 字段命名策略統一:推薦駝峰 (Java) <-> 下劃線 (JSON),Jackson 配置 mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)。

六、 總結

JSON 解析在 Java 中已是基建級能力。**Jackson 是企業級首選**,Gson 適合輕量客戶端,org.json 適合極簡場景。掌握 對象綁定 (一行代碼)、樹模型動態解析 (JsonNode)、流式解析 (大文件)、日期/Null/命名策略配置 五大核心技能,即可應對 99% 業務場景。建議項目統一封裝 JsonUtils 工具類,內部委託 Jackson,對外暴露簡潔 API,屏蔽底層庫細節,便於未來升級遷移。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved