当前位置: 首页 > 面试题库 >

Gson用多种对象类型反序列化JSON数组

龚俭
2023-03-14
问题内容

我有一些奇怪的JSON,如:

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

基于某个字段,数组中的对象是某种类型。使用Gson,我的想法是要拥有一个TypeAdapterFactory,它将那些特定类型的委托适配器发送到TypeAdapter,但是我一直挂在理解读取“
type”字段以了解要创建哪种类型的一种好方法上。在TypeAdapter中

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

会假设“类型”字段在我的JSON中排在首位。有消除这种假设的不错方法吗?


问题答案:

这是我编写的一些代码,用于处理Json中的一系列NewsFeedArticle和NewsFeedAd项目。这两个项目都实现了标记接口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();


 类似资料:
  • 我想通过Google Gson传输一个列表对象,但我不知道如何反序列化泛型类型。 我在看了这个之后尝试了什么(Balusc的回答): 编辑: 现在我有 但是,我确实在“FromJson”行得到以下异常: null

  • 我从超文本传输协议Web服务收到以下JSON响应 现在我希望能够反序列化这个。我偶然发现了来自谷歌的Gson,它最初在一些小测试用例中运行良好,但我在反序列化上面的字符串时遇到了一些困难。 我正在阅读Gson用户指南,理想情况下,我希望有一个对象,它有两个属性:和,但是字段必须是对象的,这可能会让Gson感到困难。 然后我看了这个例子,它更接近我的问题,但我仍然不太明白。在这个例子中,整个响应是一

  • 当我试图使用Gson库反序列化JSON对象数组时,我遇到了一个问题。 JSON数组的一个示例: 你怎么认为?反序列化这种JSON响应的正确Java代码是什么?

  • 我认为最好用一个例子来解释。 我有一个想要反序列化的JSON对象,它包含一个接口类型列表以及列表中的类型,但是我不确定如何让反序列化器确定列表中的具体类型: 要反序列化的类型 界面 儿童 我知道如果类型不是<code>List</code>,我可以将类型与<code>JsonSubTypes</code>一起使用,例如: 如果在父类型内,也是如此。但是当类型在类之外时,是否有一种方法可以帮助反序列

  • 问题内容: 我在反序列化以下json数组时遇到麻烦(对不起,大小): 如果将其粘贴到json-viewer中,则会得到以下结构: 现在,包含具有坐标的数组的数组具有可变大小。所以我想在Java中,整个对象应该是一个数组,其中包含数组的集合,每个数组都包含一个。就像是 但是gson不接受这一点。我收到以下错误消息: 这似乎很奇怪,因为对我来说好像不像一个数组。但这可能使我感到困惑,或多或少地迷路了…

  • 问题内容: 我正在尝试使用Gson 反序列化a ,值的类型可以变化,值“ in_wanted”可以是a 或a 。 in_wanted为: in_wanted为: 每当“ in_wanted”的值为布尔值时,我都需要该对象,并且需要一个反序列化器以返回null。用Gson做到这一点的最佳方法是什么? 问题答案: 您可以使用自定义解串器来完成此操作。首先,我们应该创建可以表示您的JSON的数据模型。