gpt4 book ai didi

java - Gson反序列化具有多种对象类型的JSON数组

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:01:14 25 4
gpt4 key购买 nike

我有一些奇怪的 JSON,例如:

[
{
"type":"0",
"value":"my string"
},
{
"type":"1",
"value":42
},
{
"type":"2",
"value": {
}
}
]

根据某个字段,数组中的对象是某个类型。使用 Gson,我的想法是有一个 TypeAdapterFactory 将那些特定类型的委托(delegate)适配器发送到 TypeAdapter,但我一直在理解阅读该“类型”字段以了解要创建哪种类型的好方法。在 TypeAdapter 中,

Object read(JsonReader in) throws IOException {
String type = in.nextString();
switch (type) {
// delegate to creating certain types.
}
}

假设“类型”字段在我的 JSON 中排在第一位。有没有合适的方法来消除这种假设?

最佳答案

这是我编写的一些代码,用于处理 Json 中的一组 NewsFeedArticle 和 NewsFeedAd 项。这两个项目都实现了一个标记接口(interface) NewsFeedItem,使我能够轻松检查 TypeAdater 是否应该用于特定字段。

public class NewsFeedItemTypeAdapterFactory implements TypeAdapterFactory {

@Override
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (!NewsFeedItem.class.isAssignableFrom(type.getRawType())) {
return null;
}

TypeAdapter<JsonElement> jsonElementAdapter = gson.getAdapter(JsonElement.class);
TypeAdapter<NewsFeedArticle> newsFeedArticleAdapter = gson.getDelegateAdapter(this, TypeToken.get(NewsFeedArticle.class));
TypeAdapter<NewsFeedAd> newsFeedAdAdapter = gson.getDelegateAdapter(this, TypeToken.get(NewsFeedAd.class));

return (TypeAdapter<T>) new NewsFeedItemTypeAdapter(jsonElementAdapter, newsFeedArticleAdapter, newsFeedAdAdapter).nullSafe();
}

private static class NewsFeedItemTypeAdapter extends TypeAdapter<NewsFeedItem> {

private final TypeAdapter<JsonElement> jsonElementAdapter;
private final TypeAdapter<NewsFeedArticle> newsFeedArticleAdapter;
private final TypeAdapter<NewsFeedAd> newsFeedAdAdapter;

NewsFeedItemTypeAdapter(TypeAdapter<JsonElement> jsonElementAdapter,
TypeAdapter<NewsFeedArticle> newsFeedArticleAdapter,
TypeAdapter<NewsFeedAd> newsFeedAdAdapter) {
this.jsonElementAdapter = jsonElementAdapter;
this.newsFeedArticleAdapter = newsFeedArticleAdapter;
this.newsFeedAdAdapter = newsFeedAdAdapter;
}

@Override
public void write(JsonWriter out, NewsFeedItem value) throws IOException {
if (value.getClass().isAssignableFrom(NewsFeedArticle.class)) {
newsFeedArticleAdapter.write(out, (NewsFeedArticle) value);

} else if (value.getClass().isAssignableFrom(NewsFeedAd.class)) {
newsFeedAdAdapter.write(out, (NewsFeedAd) value);

}

}

@Override
public NewsFeedItem read(JsonReader in) throws IOException {
JsonObject objectJson = jsonElementAdapter.read(in).getAsJsonObject();

if (objectJson.has("Title")) {
return newsFeedArticleAdapter.fromJsonTree(objectJson);

} else if (objectJson.has("CampaignName")) {
return newsFeedAdAdapter.fromJsonTree(objectJson);
}

return null;
}
}
}

然后您可以使用以下代码将其注册到 Gson。

return new GsonBuilder()
.registerTypeAdapterFactory(new NewsFeedItemTypeAdapterFactory())
.create();

关于java - Gson反序列化具有多种对象类型的JSON数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36780871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com