使用 GSON 取得 JSONObject 下所有鍵的列表
1.概述
當我們在 Java 中處理 JSON 資料時,我們每天面臨的任務之一就是提取所有鍵。乍一看,這似乎很容易;畢竟,GSON 讓 JSON 解析變得非常簡單。然而,一旦 JSON 開始嵌套,事情就會變得有點棘手。
在本教程中,我們將示範如何使用 GSON 取得JsonObject
的所有鍵(包括巢狀鍵)。我們還將編寫一些單元測試來確保我們的解決方案能夠正常運作。
2. 我們為什麼需要這個?
假設我們有一個來自 API 的 JSON 回應,並且我們想要:
- 驗證特定鍵是否存在。
- 記錄所有鍵以用於調試目的。
- 將結構扁平化,以便於比較或處理。
如果我們的 JSON 看起來很簡單,如下:
{
"name": "Henry",
"email": "[email protected]",
"age": 25
}
然後呼叫jsonObject.keySet()
為我們提供所有鍵:
[name, email, age]
但是一旦我們處理巢狀的 JSON:
{
"name": "Henry",
"email": "[email protected]",
"address": {
"city": "New York",
"zip": "10001"
}
}
jsonObject.keySet()
只會回傳:
[name, email, address]
我們遺失了巢狀的鍵,例如address.city
和address.zip
。如果我們想要一個完整的鍵列表,這可不是什麼好事。
3.如何解決?
我們可以透過編寫遞歸方法來解決這個問題。首先,我們可以使用 GSON 函式庫。它是一個非常輕量級且廣泛使用的 JSON 庫。
我們可以使用GSON ,並使用 Maven 依賴項將其新增至我們的pom.xml
中:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
讓我們看一下實作:
public static List<String> getAllKeys(JsonObject jsonObject) {
List<String> keys = new ArrayList<>();
extractKeys("", jsonObject, keys);
return keys;
}
private static void extractKeys(String prefix, JsonObject jsonObject, List<String> keys) {
Set<String> jsonKeys = jsonObject.keySet();
for (String key : jsonKeys) {
String fullKey = prefix.isEmpty() ? key : prefix + "." + key;
keys.add(fullKey);
JsonElement element = jsonObject.get(key);
if (element.isJsonObject()) {
extractKeys(fullKey, element.getAsJsonObject(), keys);
}
}
}
讓我們了解一下實現方式:
- 我們從方法
getAllKeys()
開始。它準備一個清單並呼叫extractKeys()
。 -
extractKeys()
方法遍歷目前物件的所有鍵。 - 如果值是另一個
JsonObject
,我們就會遞歸呼叫相同的方法。 - 為了讓鍵有意義,我們加入了前綴。我們儲存的不是城市,而是
address.city
。
讓我們來看看支援測試用例:
@Test
void givenJson_whenTopLevelKeys_thenGetAllKeys() {
String json = "{ \"name\":\"Henry\", \"email\":\"[email protected]\", \"age\":25 }";
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
List<String> keys = JsonKeyExtractor.getAllKeys(jsonObject);
assertEquals(3, keys.size());
assertTrue(keys.contains("name"));
assertTrue(keys.contains("email"));
assertTrue(keys.contains("age"));
}
@Test
void givenJson_whenNestedKeys_thenGetAllKeys() {
String json = "{ \"address\": { \"city\":\"New York\", \"zip\":\"10001\" } }";
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
List<String> keys = JsonKeyExtractor.getAllKeys(jsonObject);
assertEquals(3, keys.size());
assertTrue(keys.contains("address"));
assertTrue(keys.contains("address.city"));
assertTrue(keys.contains("address.zip"));
}
這樣,無論 JSON 嵌套有多深,我們都不會錯過任何東西。
4.我們可以在哪裡使用它?
現在我們已經解決了這個問題,讓我們思考一下這在實際專案中有什麼用處:
- 驗證:確保傳入的 JSON 中存在所需的金鑰。
- 稽核:記錄 JSON 有效負載的結構以進行偵錯或合規性。
- 扁平化資料:為無法很好地處理巢狀 JSON 的工具準備資料。
- 模式發現:無需手動檢查有效負載即可探索不熟悉的 API。
5. 結論
在本文中,我們建立了一個簡單的遞歸實用程序,使用 GSON 從JsonObject
中提取所有鍵。透過處理嵌套對象,我們可以確保不會遺漏任何鍵。這種方法的優點在於它非常靈活,我們可以根據需要進一步擴展它,以處理數組或應用過濾器(例如僅收集葉鍵)。
現在,下次我們需要在 Java 中使用 JSON 時,我們將有一個可靠的方法來取得每個鍵。
與往常一樣,本文中提供的程式碼可在 GitHub 上取得。