【问题标题】:Android: Using GSON to parse a response with dynamic fieldsAndroid:使用 GSON 解析具有动态字段的响应
【发布时间】:2011-11-01 14:29:52
【问题描述】:

我需要解析有关议程中事件的 JSON 响应,其中一个字段是动态的。此字段会根据事件发生的月份而变化。

现在我之前一直在使用 GSON 解析数据,但是这些都有静态字段,因此创建必要的 POJO 非常容易。但是我该如何处理动态字段呢?

我需要解析的响应是这样的:

{
  "Agenda/Future": {
    "November 2011/0": [
      {
        "id": "5675",
        "eventid": "",
        "name": "testing testing 123",
        "startdate": "nov 25",
        "datecompute": "2011-11-25T08:00:00",
        "group_month": "November 2011",
        "flg_Data": "Database"
      }
    ],
    "February 2012/1": [
      {
        "id": "5681",
        "eventid": "",
        "name": "dfd",
        "startdate": "feb 3",
        "datecompute": "2012-02-03T12:00:00",
        "group_month": "February 2012",
        "flg_Data": "Database"
      },
      {
        "id": "5679",
        "eventid": "",
        "name": "vfvd",
        "startdate": "feb 17",
        "datecompute": "2012-02-17T12:00:00",
        "group_month": "February 2012",
        "flg_Data": "Database"
      }
    ],
    "February 2013/2": [
      {
        "id": "5680",
        "eventid": "",
        "name": "df",
        "startdate": "feb 14",
        "datecompute": "2013-02-14T12:00:00",
        "group_month": "February 2013",
        "flg_Data": "Database"
      }
    ],
    "September 2013/3": [
      {
        "id": "5677",
        "eventid": "",
        "name": "fsdfsd",
        "startdate": "sep 14",
        "datecompute": "2013-09-14T12:00:00",
        "group_month": "September 2013",
        "flg_Data": "Database"
      }
    ],
    "November 2015/4": [
      {
        "id": "5676",
        "eventid": "",
        "name": "fsdfsd",
        "startdate": "nov 13",
        "datecompute": "2015-11-13T12:00:00",
        "group_month": "November 2015",
        "flg_Data": "Database"
      }
    ]
  }
}

如您所见,关于月份的对象标题是动态的。标题末尾的值以及标题本身都会根据实际月份和月份数组中的位置而变化。

根据我在 SO 的其他问题上看到的情况,我需要与 Maps 合作。 但我不太确定我将如何去做。 假设我为月份数组中包含的各个事件创建了一个名为 Event 的 POJO,我的初始化会是什么样子?

问候


我尝试了 Amir 的建议,将 Jackson 与默认的 Map 结合使用。 遗憾的是,这会创建一个大小为1Map。整个 JSON 响应被解析为单个对象。当然,这不是我想要的,因为我需要从各个事件中获取数据。

有没有人建议我如何做到这一点?通常我会很快弄清楚这些事情,但由于动态对象命名,我无法理解这一点。


我最终设法解决了这个问题。我最终使用了普通的 JSONObjects,它最终起作用了。

我用来让它工作的代码如下:

        JSONObject jsonObject = new JSONObject(response);
        JSONObject agenda = jsonObject.getJSONObject("Agenda/Future");

        if (agenda != null) {
            System.out.println(agenda.length());
            JSONArray events = agenda.names();
            if (events.length() > 0) {
                System.out.println("At least its bigger then 0. It's: "
                        + events.length());
                for (int i = 0; i < events.length(); i++) {
                    System.out.println(events.get(i).toString());
                    JSONArray test = agenda.getJSONArray(events.get(i)
                            .toString());
                    if (test != null) {
                        JSONObject testt = test.getJSONObject(0);
                        if (testt != null) {
                            System.out.println(testt.getString("name"));
                        } else {
                            System.out.println("Still empty, Check again.");
                        }
                    }
                }
            }

        } else {
            System.out.println("Agenda is completely empty, try again.");
        }

如您所见,这仍然包含测试名称,但至少它有效。 感谢大家的帮助!

【问题讨论】:

    标签: android parsing dynamic gson


    【解决方案1】:

    由于月份数据不是有效的 Java 标识符,您可能必须将 custom serialization 与 GSON 一起使用。您正在谈论使用 Map 对象,但如果您打算这样做,您最好使用 org.json 对象,例如 JSONObject,它们基本上都是基于地图/哈希表构建的。

    【讨论】:

    • 在第一次放弃这个答案后,因为 Amir 的方法似乎是我需要的,我最终尝试了正常的JSONObjects,最终帮助我解决了我的问题。所以非常感谢!接受
    【解决方案2】:

    如您所说,如果您的所有字段都是动态的,那么您可以在 pojo 中创建所有字段的超级集。但这并没有真正的帮助,我认为Map 是最好的解决方案。使用 GSON,您可以做到

    Type type = new TypeToken<Map<String, String>>(){}.getType();
    Map<String, String> map = gson.fromJson("{'key1':'123','key2':'456'}", type);
    

    这将返回一个字符串映射。

    我之前实际上并没有使用 GSON 来执行此操作。我对Jackson lib 非常满意,您可以这样做

    new ObjectMapper().readValue("...json...", Map.class)
    

    以上将返回您想要的地图地图。

    【讨论】:

    • 我可能会试一试杰克逊,但如果可能的话,我宁愿使用 GSON,因为这是我目前最有经验的一个。但是,您的快速示例在 Map 中使用了 2 个 Strings,您认为如果我使用类似的东西会起作用吗:Type type = new TypeToken&lt;Map&lt;String, Event&gt;&gt;(){}.getType(); Map&lt;String, Event&gt; map = gson.fromJson(myJsonrResponse, type); 就像我在原帖中所说的那样?
    • 对于杰克逊,我知道这会奏效,因为我已经尝试过了。使用 GSON,我认为事件地图会起作用。但我不确定地图的地图。
    • 我终于设法解决了我的问题,但 mjmarsh 给了我最终成功的建议。非常感谢您提到杰克逊,它看起来确实很有用,所以我相信我将来会使用它
    • 没问题。不久前,我注意到两个最好的 json 库是 GSON 和 Jackson。我发现杰克逊的速度要快得多。请参阅这些链接 cowtowncoder.com/blog/archives/2009/09/entry_326.htmlcode.google.com/p/thrift-protobuf-compare/wiki/Benchmarkingstackoverflow.com/questions/2378402/jackson-vs-gson。编码愉快!
    猜你喜欢
    • 2011-11-30
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 2019-07-17
    相关资源
    最近更新 更多