[英]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.