Android: использование GSON для анализа ответа с помощью динамических полей - PullRequest
2 голосов
/ 01 ноября 2011

Мне нужно проанализировать ответ 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. Но я не совсем уверен, как бы я поступил так. Допустим, я создаю POJO с именем Event для отдельных событий, содержащихся в массиве месяцев, как будет выглядеть моя инициализация?

Привет


Я попробовал предложение Амира, используя Джексона со значением по умолчанию Map. К сожалению, это создает 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 ]

1 голос
/ 01 ноября 2011

Поскольку данные месяца не являются допустимыми идентификаторами Java, вам, вероятно, придется использовать пользовательскую сериализацию с GSON. Вы говорите об использовании объектов Map, но если вы собираетесь это сделать, вы также можете использовать org.json объекты, такие как JSONObject, которые в любом случае в основном построены на картах / хеш-таблицах.

1 голос
/ 01 ноября 2011

Если все ваши поля, как вы сказали, являются динамическими, то вы можете создать супер-набор всех полей в Pojo. Но это не очень помогает, и я думаю, Map - лучшее решение. С GSON вы можете сделать

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

Это вернет карту строк.

Хотя на самом деле я раньше не использовал GSON для этого. Я был очень счастлив с Джексоном lib и с этим вы можете сделать

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

Выше вернется карта карт, которая вам нужна.

...