2011-11-01 51 views
2

我需要解析关于议程中事件的JSON响应,其中的字段是动态的。该字段根据事件发生的月份而变化。Android:使用GSON解析带有动态字段的响应

现在我以前一直在用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试图阿米尔的建议。 不幸的是,这会创建一个尺寸为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."); 
     } 

正如你所看到的,这还包含测试的名称,但至少它的工作原理。 感谢大家的帮助!

+0

+1不错的问题。 – Venky

回答

1

由于月份数据不是有效的java标识符,您可能必须使用custom serialization与GSON。您正在讨论使用Map对象,但如果您打算这样做,那么您可能还会使用像JSONObject这样的对象,它们基本上都是基于地图/散列表构建的。

+0

自从Amir的见解看起来我需要一个答案后,第一次抛弃这个答案后,我最终尝试了正常的'JSONObject's,最终它帮助我解决了我的问题。非常感谢!公认 –

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) 

上面会返回地图的地图这是你想要的。

+0

我可能会给杰克逊一个这样的旋风,但如果可能的话,我宁愿使用GSON,因为那是我目前拥有最多经验的人。 然而,你的快速示例在'Map'中使用了2个'Strings',你认为它会起作用吗?如果我使用类似的东西: 'Type type = new TypeToken >(){}。getType (); Map map = gson.fromJson(myJsonrResponse,type);' 像我在我原来的帖子中说过的?与杰克逊 –

+0

我知道这将工作,因为我已经尝试过。对于GSON,我认为事件地图将起作用。但我不确定地图的地图。 –

+0

我设法最终解决了我的问题,但是mjmarsh给了我最后工作的建议。非常感谢提到杰克逊,它确实看起来相当有用,所以我相信我会在将来使用它 –