【问题标题】:How to parse JSON object with Gson to map of unknown type如何使用 Gson 解析 JSON 对象以映射未知类型
【发布时间】:2017-02-07 19:54:12
【问题描述】:

我开始使用带有 Retrofit 的 Gson,而不是 Jackson,来解析来自 Wikipedia API 的一些 Json,其结构如下:

{
  "batchcomplete": "",
  "query": {
    "pages": {
      "21721040": {
        "pageid": 21721040,
        "ns": 0,
        "title": "Stack Overflow",
        "extract": "Stack Overflow

在“pages”对象中,我试图将下一个块映射到键/值类型 String 和 WikiSummary 的 Map 对象,但该对象返回 null。通过 Jackson,如果我没记错的话,你可以像这样直接映射,因为我不知道“pages”在其中包含的对象值。

WikiPages.class

public class WikiPages {

    public Map<String, WikiSummary> summaryMap;

    public WikiPages(Map<String, WikiSummary> summaryMap) {
        this.summaryMap = summaryMap;
    }

    public Map<String, WikiSummary> getSummaryMap() {
        return summaryMap;
    }

    public void setSummaryMap(Map<String, WikiSummary> summaryMap) {
        this.summaryMap = summaryMap;
    }

}

维基摘要

public class WikiSummary {

    public int pageid;
    public String title;
    public String extract;

    public WikiSummary(int pageid, String title, String extract) {
        this.pageid = pageid;
        this.title = title;
        this.extract = extract;
    }

    public int getPageid() {
        return pageid;
    }

    public void setPageid(int pageid) {
        this.pageid = pageid;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getExtract() {
        return extract;
    }

    public void setExtract(String extract) {
        this.extract = extract;
    }
}

【问题讨论】:

  • 因为您的 json 属性是动态的,最简单的解决方案是将页面设为 HashMap。 Gson 可以很好地解析。

标签: android json gson retrofit


【解决方案1】:

您似乎不需要WikiPages,因为它本身必须是一个映射(对于最简单的 Gson 配置;否则需要更复杂的反序列化器)。因此,Gson 正在寻找给定 JSON 中不存在的 summaryMap 属性,这就是为什么它是 null。以下映射

final class WikiResponse {
    @SerializedName("batchcomplete")
    final String batchComplete = null;
    @SerializedName("query")
    final WikiQuery query = null; // this is what you seem to be looking for
}

final class WikiQuery {
    @SerializedName("pages")
    final Map<String, WikiSummary> pages = null;
}

final class WikiSummary {
    @SerializedName("pageid")
    final int pageId = Integer.valueOf(0); // can't be null, but a simple `0` literal will be inlined
    @SerializedName("title")
    final String title = null;
    @SerializedName("extract")
    final String extract = null;
}

可以表示 JSON(假设上面的 DTO 是传入的,而不是设计为传出的 [否则增强];并且 Gson 可以为最终字段分配实际值)。解析给定的 JSON 并使用 wikiResponse.query.pages.get("21721040").title 查询反序列化的 POJO 将得到 Stack Overflow

【讨论】:

  • 太棒了!那行得通。我想用我的 WikiSummary 内容制作地图,而不是“页面”对象。
【解决方案2】:
JSONObject pagesObject = queryObject.getJSONObject("pages");
Set<String> keys = pagesObject.keySet();
for (String k : keys) {
    JSONObject desiredKeyValues = elements.getJSONObject(k);
}

【讨论】:

  • 请您在回答中添加一些细节吗?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-05
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多