在 Java 中將 JSON 物件轉換為 JSON 數組
1.概述
JSON(JavaScript 物件表示法)是一種用於資料交換的輕量級結構化格式。現代軟體廣泛使用 JSON 進行資料交換、配置和 API 通訊。在 Java 中,處理 JSON 通常需要使用 org.json、Jackson 或 Gson 等函式庫。雖然將 JSON 物件轉換為 JSON 陣列看似簡單,但正確的方法取決於輸入結構和所需的輸出格式。
在本教程中,我們將示範如何使用不同的函式庫將 JSON 物件轉換為 JSON 數組,並提供程式碼範例和 JUnit 測試進行驗證。
2. 用例和注意事項
在與 REST API、資料管道或設定檔互動的應用程式中,將 JSON 物件轉換為 JSON 陣列是一項常見需求。當最初建模為鍵值對的資料必須進行序列化、迭代或重新格式化以相容於前端框架或外部系統時,這種轉換通常是必要的。例如,API 可能需要物件數組而不是映射,尤其是在渲染表格資料或處理表單提交時。
在選擇轉換方法之前,開發人員應該評估他們是否只需要 JSON 物件中的值,還是需要將鍵和值作為不同的實體。我們還應該考慮如何使用產生的 JSON 陣列。無論是用於顯示、傳輸或進一步操作,因為這直接影響庫和轉換策略的選擇。
3. 轉化方法
現在讓我們介紹將 JSON 物件轉換為 JSON 陣列的三種不同方法。對於每個函式庫,我們首先建立一個方法來封裝邏輯,然後使用對應的 Junit 驗證其正確性。
3.1. 使用org.json
庫
org.json
庫簡單易用,並且已包含在許多 Java 專案中。該庫提供了用於處理 JSON 物件的簡潔且直接的 API。它為JSONObject
和JSONArray
提供了簡單的 API。讓我們創建一些方法來處理這兩種常見場景:
JSONArray convertValuesToArray(JSONObject jsonObject) {
return new JSONArray(jsonObject.toMap().values());
}
然後,此方法提取values()
集合並將其包裝在JSONArray
中,從而僅產生一個值數組。
現在讓我們透過傳遞一個簡單的JSONObject
並檢查所有值是否出現在JSONArray
中來驗證該方法:
@Test
void givenFlatJSONObject_whenConvertValues_thenJSONArrayOfValues() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", 1);
jsonObject.put("name", "Alice");
OrgJsonConverter converter = new OrgJsonConverter();
JSONArray result = converter.convertValuesToArray(jsonObject);
assertEquals(2, result.length());
assertTrue(result.toList().contains("Alice"));
}
接下來,我們加入另一個方法來建構一個JSONArray
,其中每個元素都是一個鍵值對,表示為其自己的JSONObject
:
JSONArray convertToEntryArray(JSONObject jsonObject) {
JSONArray result = new JSONArray();
for (String key : jsonObject.keySet()) {
JSONObject entry = new JSONObject();
entry.put("key", key);
entry.put("value", jsonObject.get(key));
result.put(entry);
}
return result;
}
此方法遍歷JSONObject
中的每個鍵並建立一個包含兩個欄位「key」和「value」的新JSONObject
。
在此測試中,我們驗證每個鍵值對是否正確轉換為JSONObject
,並且在產生的JSONArray
中包含key
和value
欄位。
@Test
void givenFlatJSONObject_whenConvertToEntryArray_thenJSONArrayOfObjects() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("language", "Java");
jsonObject.put("framework", "Spring");
OrgJsonConverter converter = new OrgJsonConverter();
JSONArray result = converter.convertToEntryArray(jsonObject);
assertEquals(2, result.length());
assertEquals("language", result.getJSONObject(0).get("key"));
}
3.2. 使用 Jackson 和自訂邏輯
Jackson 是一個用於處理 JSON 資料的多功能 Java 函式庫。它利用自身功能,對 JSON 結構提供了更強大的控制。雖然 Jackson 主要使用樹形模型,但我們仍然可以透過內部轉換將其與JSONObject
整合。
讓我們寫一個接受JSONObject
的方法,將其轉換為 Jackson 的內部模型,並傳回一個ArrayNode:
ArrayNode convertToArray(JSONObject jsonObject) {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.convertValue(jsonObject.toMap(), JsonNode.class);
ArrayNode result = mapper.createArrayNode();
jsonNode.fields().forEachRemaining(entry -> {
ObjectNode obj = mapper.createObjectNode();
obj.put("key", entry.getKey());
obj.set("value", entry.getValue());
result.add(obj);
});
return result;
}
我們先將JSONObject
轉換為 Map ,然後使用 Jackson 的convertValue()
轉換為JSONNode
。之後,我們循環遍歷所有字段,並建立一個包含新鍵值對的ArrayNode
。這種方法對於更複雜的整合非常有用。
讓我們透過轉換具有兩個鍵值對的JSONObject
並斷言它將它們構造為結果ArrayNode
中的單獨鍵值物件來測試基於 Jackson 的方法:
@Test
void givenJSONObject_whenConvertToArray_thenArrayNodeOfKeyValueObjects() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("country", "India");
jsonObject.put("code", "IN");
JacksonConverter converter = new JacksonConverter();
ArrayNode result = converter.convertToArray(jsonObject);
assertEquals(2, result.size());
assertEquals("country", result.get(0).get("key").asText());
}
3.3. 使用 Gson 和 JSON 對象
Gson 是下一個 Java JSON 函式庫。它不直接接受 JSON 對象,但我們仍然可以透過在內部將其轉換為 Map 來使用它。讓我們建立一個方法,從JSONObject
建立JsonArray
,其中每個元素都是一個鍵值對:
JsonArray convertToKeyValueArray(JSONObject jsonObject) {
JsonArray result = new JsonArray();
jsonObject.keySet().forEach(key -> {
JsonObject entry = new JsonObject();
entry.addProperty("key", key);
entry.add("value", com.google.gson.JsonParser.parseString(jsonObject.get(key).toString()));
result.add(entry);
});
return result;
}
我們遍歷JSONObject
的鍵,並為每個條目建立一個新的JSONObject
。每個新物件都包含鍵和解析後的值。這種方法與 Gson API 相容。
在這裡,我們檢查JSONObject
中的每個條目是否成為JsonArray
中的鍵值物件:
@Test
void givenJSONObject_whenConvertToKeyValueArray_thenJsonArrayWithObjects() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("brand", "Tesla");
jsonObject.put("year", 2024);
GsonConverter converter = new GsonConverter();
JsonArray result = converter.convertToKeyValueArray(jsonObject);
assertEquals(2, result.size());
assertEquals("brand", result.get(0).getAsJsonObject().get("key").getAsString());
}
4. 結論
在本文中,我們探索如何使用最受歡迎的 Java JSON 函式庫將 JSON 物件轉換為 JSON 陣列org.json
庫為我們提供了簡單易用的工具, Gson
用於僅值轉換和鍵值對轉換。 Jackson 在處理複雜資料模型或與其他基於 Jackson 的功能整合時Jackson
出色。 Gson 提供了一種輕量級且簡潔的方法,可在 Android 或微服務環境中實現相同的功能。
我們應該根據應用需求選擇合適的方法。每種方法都已準備就緒,並且易於驗證。與往常一樣,這些範例的程式碼可在 GitHub 上取得。