Android:使用GSON解析动态字段的响应

时间:2011-11-01 14:29:52

标签: android parsing dynamic gson

我需要解析关于议程中事件的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,我的初始化会是什么样的?

此致


我使用默认Map的杰克逊尝试过Amir的建议。 遗憾的是,这会创建一个Map,其大小为1。整个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.");
        }

正如您所看到的,这仍然包含测试名称,但至少它可以工作。 感谢大家的帮助!

2 个答案:

答案 0 :(得分:1)

如果您所说的所有字段都是动态的,那么您可以在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)

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

答案 1 :(得分:1)

由于月份数据不是有效的java标识符,因此您可能必须在GSON中使用 custom serialization 。你正在讨论使用Map对象,但是如果你打算这样做,你可能也会使用像JSONObject这样的 org.json 对象,它们基本上都建立在map / hashtables上。