2012-04-22 76 views
4

我一直在使用GSON库来解析所有json字符串并获取JSON对象。 但现在我需要分析是这样的:如何使用GSON解析Android中的动态“键”JSON

{ 
    "status":1, 
    "info":[ 
     { 
     "\u5a31\u4e50":"\u51b7\u76d8,\u9ad8\u811a\u676f,\u6211\u7684\u7cd6\u679c\u5c4b,\u670d\u52a1\u4e1a\u6d88\u8d39\u52b5" 
     }, 
     { 
     "\u7f8e\u5986":"\u4e2a\u62a4|\u5316\u5986#\u9762\u90e8\u62a4\u7406,\u4e2a\u4eba\u536b\u751f,\u8eab\u4f53\u62a4\u7406,\u9999\u6c34\u9999\u6c1b,\u6c90\u6d74|\u7f8e\u53d1\u7528\u54c1,\u5f69\u5986,\u7cbe\u6cb9SPA,\u773c\u90e8\u62a4\u7406,\u78e8\u7802\u53bb" 
     }, 
     { 
     "\u8863\u670d":"\u670d|\u9970|\u978b|\u5e3d#\u670d\u88c5,\u978b\u9774,\u5185\u8863,\u914d\u9970,\u536b\u8863,\u4f11\u95f2\u88e4,T\u6064,\u88d9\u5b50,\u886c\u886b,\u9488\u7ec7\u886b,\u5a74\u5e7c\u513f\u670d\u9970" 
     } 
    ], 
    "total":3 
} 

的重点领域是动态的,所以我不知道如何写一个模型类阅读本。

+0

键怎么来是动态的?我认为键的内容可以是动态的...你是否自己手动生成json字符串...? – waqaslam 2012-04-22 12:06:22

回答

9

您希望您的模型类看起来如何?

statustotal可能是int,所以只留下info

作为一个实验,只需添加一个字段Object info,看看GSON将其设置为ArrayList<LinkedHashMap<String, String>> - 丑陋不堪,通过密钥访问,但所有的数据是存在的。鉴于信息,一类模型的最快方法是:

class Something { 
    int status; 
    List<Map<String, String> info; 
    int total; 
} 

如果你有过怎样的生成JSON,我建议从对象[{a:b},{c:d},{e:f}]只是一个对象{a:b,c:d,e:f}数组改变info结构控制。

class Something { 
    int status; 
    Map<String, String> info; 
    int total; 
} 

如果你想在不改变JSON格式,后者模型类,你必须写:有了这个,你可以只将其与所有喜欢的密钥访问,keys()values()好处映射到Map<String, String>一个TypeAdapter(或JsonDeserializer,如果你只是感兴趣的解析JSON,而不是从你的模型类生成它)。

这里有一个JsonDeserializer帽子将您的原始info JSON属性映射到一个普通的Map<String, String>

class ArrayOfObjectsToMapDeserializer 
    implements JsonDeserializer<Map<String, String>> { 

    public Map<String, String> deserialize(JsonElement json, Type typeOfT, 
     JsonDeserializationContext context) throws JsonParseException { 
    Map<String, String> result = new HashMap<String, String>(); 

    JsonArray array = json.getAsJsonArray(); 
    for (JsonElement element : array) { 
     JsonObject object = element.getAsJsonObject(); 
     // This does not check if the objects only have one property, so JSON 
     // like [{a:b,c:d}{e:f}] will become a Map like {a:b,c:d,e:f} as well. 
     for (Entry<String, JsonElement> entry : object.entrySet()) { 
     String key = entry.getKey(); 
     String value = entry.getValue().getAsString(); 
     result.put(key, value); 
     } 
    } 
    return result; 
    } 
} 

您需要注册与此类似这种风俗JsonDeserializer

GsonBuilder builder = new GsonBuilder(); 
builder.registerTypeAdapter(
    new TypeToken<Map<String, String>>() {}.getType(), 
    new ArrayOfObjectsToMapDeserializer()); 
Gson gson = builder.create(); 

注意不管此注册了任何Map<String, String>自定义解串器中遇到什么课了。如果你不想要这个,你还需要创建一个自定义的TypeAdapterFactory,然后在返回之前检查声明类以及解串器的实例。

+0

这是工作!谢谢! – gulin 2012-04-22 12:46:15

+1

不客气:)我只是添加了一个'JsonDeserializer',允许您在不更改JSON格式的情况下使用更好的'Map '。 – 2012-04-22 12:48:04

1

这里有一个解决方案,它不需要制作JsonDeserializer。

所有你可以创建一个JsonElement在地图Map.Entry<String, JsonElement>和使用for循环遍历条目

//parsing string response to json object 
JsonObject jsonObject = (JsonObject) new JsonParser().parse(jsonString); 
    //getting root object 
JsonObject dateWiseContent = jsonObject.get("rootObject").getAsJsonObject(); 

     for (Map.Entry<String, JsonElement> entry : dateWiseContent.entrySet()) { 

        //this gets the dynamic keys 
        String dateKey = entry.getKey(); 

        //you can get any thing now json element,array,object according to json. 

        JsonArray jsonArrayDates = entry.getValue().getAsJsonArray(); 
     } 

更多here