[英]Deserialize nested object with GSON
我正在嘗試反序列化以下結構
{ meta: { keywords: [a, b, c, d]} ... }
其他有效結構是
{ meta: { keywords: "a,b,c,d"} ... }
和
{ meta: {keywords: "a"} ...}
我有這門課
public class Data {
@PropertyName("meta")
MetaData meta;
...
}
public class MetaData {
List<String> keywords;
...
}
和一個自定義解串器
public static class CustomDeserilizer implements JsonDeserializer<MetaData>{
@Override
public MetaData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
List<String> keywords = null;
Gson gson = new Gson();
MetaData metaData = gson.fromJson(json, AppMetaData.class);
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("keywords")) {
JsonElement elem = jsonObject.get("keywords");
if (elem != null && !elem.isJsonNull()) {
if (jsonObject.get("keywords").isJsonArray()) {
keywords = gson.fromJson(jsonObject.get("keywords"), new TypeToken<List<String>>() {
}.getType());
} else {
String keywordString = gson.fromJson(jsonObject.get("keywords"), String.class);
keywords = new ArrayList<String>();
list.addAll(Arrays.asList(keywordString.split(",")));
}
}
}
metaData.setKeywords(keywords);
}
然后我嘗試應用脫硫劑:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Data.class,new CustomDeserilizer())
.create();
但是我得到一個解析錯誤,因為試圖反序列化數據而不是元數據,我怎樣才能應用這個反序列化器來使它正常工作?
我解決了它,為我的數據類創建了一個反序列化器。
public static class DataDeserilizer implements JsonDeserializer {
@Override
public Data deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Gson gson = new Gson();
Data data = gson.fromJson(json, Data.class);
JsonObject jsonObject = json.getAsJsonObject();
if (jsonObject.has("meta")) {
JsonElement elem = jsonObject.get("meta");
if (elem != null && !elem.isJsonNull()) {
Gson gsonDeserializer = new GsonBuilder()
.registerTypeAdapter(MetaData.class, new CustomDeserilizer())
.create();
gsonDeserializer.fromJson(jsonObject.get("meta"), Data.class);
}
}
return data;
}
}
和
Gson gson = new GsonBuilder()
.registerTypeAdapter(Data.class,new DataDeserilizer())
.create();
很明顯,但是有更優雅的解決方案嗎?
首先,將您的類重命名為 meta 而不是 metadata 並使關鍵字 String 而不是 List。然后使用以下內容將您的 JSonString 映射到您的對象中。
Gson gson = new GsonBuilder().create();
Meta meta = gson.from(yourJsonString,Meta.class);
為了僅獲取關鍵字,您需要這個。
JsonObject jsonObject = new JsonObject(yourJSonString);
String data = jsonObject.getJsonObject("meta").getString("keywords");
關鍵字是 JsonObject 而不是 JsonArray,因此您不能直接將其映射到 List。 您可以拆分字符串以獲取數組中的關鍵字。
String keywords[] = data.split(",");
這是一個簡潔的解決方案,它利用 Java 繼承來表示嵌套結構; 因此不需要提供任何實際的實例成員字段(映射等)來捕獲 GSON 映射的嵌套String
數據。
第 1 步:為了可讀性,創建一個空對象來表示嵌套映射
public class StateRegionCitiesMap extends HashMap<String, List<String>> {
}
第二步:添加一行實際代碼做映射; 無需管理其他序列化/反序列化邏輯
protected void loadContent(JsonObject stateRegionsJsonObject) {
HashMap<String, StateRegionCitiesMap> stateRegionCitiesMap =
mGson.fromJson(
stateRegionsJsonObject,
new TypeToken<HashMap<String, StateRegionCitiesMap>>() {
}.getType()
);
}
或者,您可以完全跳過包裝類,直接將<String, List<String>>
放入 GSON 調用中。 但是,我發現一個明確的對象有助於通知/提醒正在閱讀代碼的人,目的是什么。
示例 JSON:
StateRegionCitiesMap
類表示多層地圖結構,例如:
[US State] -> [State-Region Key] -> [Sub-Region Key] -> CitiesArray[]
"CA": {
"Central CA": {
"Central Valley": [
"FRESNO",
"VISALIA"
],
"Sacramento Area": [
"SACRAMENTO",
"EL DORADO HILLS"
]
},
這假設可以輕松實現您想要的。 您應該定義一個內部靜態類。 您可以保持嵌套類以將關鍵字定義為類關鍵字等。只要記住在包含類中有一個字段,即在您的內部類中有private Keywords keywords;
在您的主要課程中:
Gson gson = new Gson();
Data data = gson.fromJson(SOME_JSON_STRING, Data.class);
在一個名為 Data 的類中:
public class Data {
private Meta meta;
static class Meta{
private String[] keywords;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.