1. 概述
JSON(JavaScript Object Notation)是一種輕量級、結構化的數據交換格式。現代軟件廣泛使用 JSON 進行數據交換、配置和 API 通信。在 Java 中,與 JSON 的交互通常涉及 org.json、Jackson 或 Gson 等庫。雖然將 JSON 對象轉換為 JSON 數組可能看起來簡單直接,但正確的做法取決於輸入結構和所需的輸出格式。
在本教程中,我們將演示如何使用不同的庫將 JSON 對象轉換為 JSON 數組,並提供帶有代碼示例和 JUnit 測試的驗證。
2. 使用場景與考量
將 JSON 對象轉換為 JSON 數組是與 REST API、數據管道或配置文件交互的應用程序中常見的需求。這種轉換通常在原始數據以鍵值對建模時變得必要,需要對數據進行序列化、迭代或重新格式化,以與前端框架或外部系統兼容。例如,API 可能期望對象數組而不是映射,尤其是在呈現表格數據或處理表單提交時。
在選擇轉換方法之前,開發人員應評估他們是否只需要 JSON 對象的值,或者需要將鍵和值作為獨立實體。我們還應考慮如何使用生成的 JSON 數組。無論是為了顯示、傳輸還是進一步操作,都會直接影響庫的選擇和轉換策略。
3. 轉換方法
現在,我們來探討三種將 JSON 對象轉換為 JSON 數組的不同方法。對於每種庫,我們首先將邏輯封裝到一個方法中,然後使用相應的 Junit 驗證其正確性。
3.1. 使用 org.json 庫
org.json 庫簡單易用,在許多 Java 項目中得到廣泛應用。該庫提供了一個簡潔明瞭的 API,用於處理 JSON 對象。它提供了對 JSONObject 和 JSONArray 的直接支持。下面我們創建一個幾個方法來處理常見的場景:
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 中的每個鍵,並創建一個新的 JSONObject,其中包含“key”和“value”兩個字段。
在本次測試中,我們驗證每個鍵值對是否正確轉換為包含結果 JSONArray 中的 key 和 value 字段的 JSONObject。
@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 是一個多用途的 Java 庫,用於處理 JSON 數據。它通過其功能,提供了對 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 進行轉換來測試基於 Jackson 的方法,並斷言它們在結果的 ArrayNode 中以單獨的鍵值對象進行結構化。
@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 來使用它。 讓我們創建一個方法,該方法從 JsonArray 中創建一個 JSONObject,其中每個元素都是鍵值對:
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 數組的方法。<em data-start="8501" data-end="8511">org.json</em > 庫為我們提供了簡單易用的工具,用於值僅轉換和鍵值對轉換。Jackson 在處理複雜的數據模型或與其他 Jackson 功能集成時表現出色。`Gson 則為 Android 或微服務環境提供了輕量級且簡潔的方式來實現相同的功能。