2013-11-20 32 views
4

我收到JSON这样我怎么反序列化对象的不同阵列GSON

[ 
    { 
    "albums" : [ 
     {"id":"0", "name":"name"}, 
     {"id":"1", "name":"name"} 
    ], 
    "name":"name" 
    }, 
    { 
    "tracks" : [ 
     {"id":"0", "name":"name", "duration":"3:30"}, 
     {"id":"1", "name":"name", "duration":"2:40"} 
    ], 
    "name":"name" 
    }, 
    { 
    "playlists" : [ 
     {"id":"0", "name":"name", "tracksCount":"3"}, 
     {"id":"1", "name":"name", "tracksCount":"40"} 
    ], 
    "name":"name" 
    } 
] 

当然我实现类的曲目,专辑和播放列表包含了所有的领域和类

Tracks { 
    String name; 
    List<Track> tracks; 
} 
Albums { 
    String name; 
    List<Album> albums; 
} 
Playlists { 
    String name; 
    List<Playlist> playlists; 
} 

我“M试图与反序列化它:

Gson gson = new Gson(); 
JsonResponse[] rez = gson.fromJson(str, JsonResponse[].class); 

其中JsonResponse为

class JsonResponse { 
    Albums albums; 
    Tracks tracks; 
    Playlists playlists; 
} 

但我得到的错误:

11-20 19:24:55.210: E/AndroidRuntime(5432): FATAL EXCEPTION: main 11-20 19:24:55.210: E/AndroidRuntime(5432): com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 13 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.Gson.fromJson(Gson.java:803) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.Gson.fromJson(Gson.java:768) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.Gson.fromJson(Gson.java:717) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.Gson.fromJson(Gson.java:689) 11-20 19:24:55.210: 11-20 19:24:55.210: E/AndroidRuntime(5432): at android.os.ResultReceiver$MyRunnable.run(ResultReceiver.java:43) 11-20 19:24:55.210: E/AndroidRuntime(5432): at android.os.Handler.handleCallback(Handler.java:587) 11-20 19:24:55.210: E/AndroidRuntime(5432): at android.os.Handler.dispatchMessage(Handler.java:92) 11-20 19:24:55.210: E/AndroidRuntime(5432): at android.os.Looper.loop(Looper.java:130) 11-20 19:24:55.210: E/AndroidRuntime(5432): at android.app.ActivityThread.main(ActivityThread.java:3687) 11-20 19:24:55.210: E/AndroidRuntime(5432): at java.lang.reflect.Method.invokeNative(Native Method) 11-20 19:24:55.210: E/AndroidRuntime(5432): at java.lang.reflect.Method.invoke(Method.java:507) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 11-20 19:24:55.210: E/AndroidRuntime(5432): at dalvik.system.NativeStart.main(Native Method) 11-20 19:24:55.210: E/AndroidRuntime(5432): Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 13 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374) 11-20 19:24:55.210: E/AndroidRuntime(5432): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165) 11-20 19:24:55.210: E/AndroidRuntime(5432): ... 21 more

附: json响应中的某些项可能会丢失。例如

[ 
    { 
    "albums" : [ 
     {"id":"0", "name":"name"}, 
     {"id":"1", "name":"name"} 
    ], 
    "name":"name" 
    } 
] 

那么,什么是问题,我该如何反序列化这个JSON?

顺便说一句我不能改变JSON。所以我需要一个解析它的代码。

+0

我不能改变JSON。所以我需要一个解析它的代码。 –

+0

希望您拥有专辑,曲目和播放列表类,只需在JsonResponse中进行更改,除了JsonResonse类中的小错误外,您的方法是正确的。 –

回答

1

谢谢大家的帮助!这是我的解决方案。

public class JsonResponse { 
    public static class Item { 
     String name; 
    } 

    public static class Tracks extends Item { 
     List<Track> tracks; 
    } 

    public static class Albums extends Item { 
     List<Album> albums; 
    } 

    public static class Playlists extends Item { 
     List<Playlist> playlists; 
    } 

    public static class JsonResponseDeserialize implements JsonDeserializer<List<? extends Item>> { 
     Gson gson = new Gson(); 
     @Override 
     public List<? extends Item> deserialize(JsonElement el, Type type, JsonDeserializationContext context) throws JsonParseException { 
      List<Item> ls = new ArrayList<Item>(); 
      JsonArray jarr = el.getAsJsonArray(); 
      for (JsonElement e : jarr) { 
       Item i; 
       if (e.getAsJsonObject().get("tracks") != null){ 
        i = gson.lsomJson(e, Tracks.class); 
        if (i != null) { 
         ls.add(i); 
         continue; 
        } 
       } 
       if (e.getAsJsonObject().get("albums") != null){ 
        i = gson.lsomJson(e, Albums.class); 
        if (i != null) { 
         ls.add(i); 
         continue; 
        } 
       } 
       if (e.getAsJsonObject().get("playlists") != null){ 
        i = gson.lsomJson(e, Playlists.class); 
        if (i != null) { 
         ls.add(i); 
         continue; 
        } 
       } 
      } 
      return ls; 
     } 
    } 

    private Tracks _tracks; 
    private Albums _albums; 
    private Playlists _playlists; 
} 

反序列化:

private static List<? extends Item> getDatalsomJson(String jsonString) { 
    Type type = new TypeToken<List<? extends JsonResponse.Item>>(){}.getType(); 
    GsonBuilder gb = new GsonBuilder(); 
    gb.registerTypeAdapter(type, new JsonResponse.JsonResponseDeserialize()); 
    Gson gson = gb.create(); 
    List<? extends Item> ls = gson.lsomJson(jsonString, type); 
    return ls; 
} 
+0

lsomJson无法找到它 – Moorthy

0

您发布的JSON不会显示JSONResponse对象的数组,而是它包含类型为Album,Tracks和Playlists的JSON对象。如果你有这个代替这将是不同的:

[ 
    { 
    { 
     "albums" : [ 
     {"id":"0", "name":"name"}, 
     {"id":"1", "name":"name"} 
     ], 
     "name":"name" 
    }, 
    { 
     "tracks" : [ 
     {"id":"0", "name":"name", "duration":"3:30"}, 
     {"id":"1", "name":"name", "duration":"2:40"} 
     ], 
     "name":"name" 
    }, 
    { 
     "playlists" : [ 
     {"id":"0", "name":"name", "tracksCount":"3"}, 
     {"id":"1", "name":"name", "tracksCount":"40"} 
     ], 
     "name":"name" 
    } 
    } 
] 

另外,如果你的对象最终是太复杂了,还记得你总是可以实现自己的JSONDeserializer类,并在GSONBuilder对象进行注册调用创建权之前( ) 在上面。

+0

我无法更改JSON。所以我需要一个解析它的代码。 –

+0

我明白JSON结构不在你的控制之下,但是你误解了你的东西:你没有一个JSONResponse对象的数组,但是有一组播放列表,Track等等......所以没问题,我只需要实现你自己的解串器;这里是一个[示例](http://stackoverflow.com/questions/6096940/how-do-i-write-a-custom-json-deserializer-for-gson) – Miquel

1

做这样

你的数据

String json = "[{\"albums\":[{\"id\":\"0\",\"name\":\"name\"},{\"id\":\"1\",\"name\":\"name\"}],\"name\":\"name\"},{\"tracks\":[{\"id\":\"0\",\"name\":\"name\",\"duration\":\"3:30\"},{\"id\":\"1\",\"name\":\"name\",\"duration\":\"2:40\"}],\"name\":\"name\"},{\"playlists\":[{\"id\":\"0\",\"name\":\"name\",\"tracksCount\":\"3\"},{\"id\":\"1\",\"name\":\"name\",\"tracksCount\":\"40\"}],\"name\":\"name\"}]"; 

你的POJO

class JsonResponse { 
     ArrayList<Album> albums; 
     ArrayList<Track> tracks; 
     ArrayList<Playlist> playlists; 
     String name; 
    @Override 
    public String toString() { 
     return "JsonResponse [albums=" + albums + ", tracks=" + tracks 
       + ", playlists=" + playlists + ", name=" + name + "]"; 
    }  
} 



class Track{ 
    int id; 
    String name; 
    String duration; 
    @Override 
    public String toString() { 
     return "Track [id=" + id + ", name=" + name + ", duration=" + duration 
       + "]"; 
    }  
} 

class Album{ 
    int id; 
    String name; 
    @Override 
    public String toString() { 
     return "Album [id=" + id + ", name=" + name + "]"; 
    } 
} 

class Playlist{ 
    int id; 
    String name; 
    int tracksCount; 
    @Override 
    public String toString() { 
     return "Playlist [id=" + id + ", name=" + name + ", tracksCount=" 
       + tracksCount + "]"; 
    } 

} 

这里反序列化的阵列。

JsonParser parser = new JsonParser(); 
    JsonArray Jarray = parser.parse(json).getAsJsonArray(); 
    Gson gson = new Gson(); 
    for(JsonElement obj : Jarray) 
    { 
     JsonResponse jsonResponse = gson.fromJson(obj , JsonResponse.class); 
     System.out.println(jsonResponse); 
    } 
0

其实你在JsonResponse类中犯了错误。

其清晰的形式表明您的json格式,它从数组开始,而在JsonResponse类中,您只是编写单个对象而不是对象集合。如果你仔细看看Gson的例外情况为 “BEGIN_OBJECT but was BEGIN_ARRAY”。这意味着Gason拥有专辑,曲目和播放列表,而不是专辑,曲目和播放列表类的对象。

只要你需要JsonResponse类变化不大如下

private List<Albums> albums; 
private List<Tracks> tracks; 
private List<Playlists> playlists; 
+0

JsonResponse类包含对象,但不列出/数组,因为那里是列表/数组旁边的字符串字段“名称”。它是类专辑的一个对象,其中包含列表专辑;和字符串名称; –

+0

每个列表包含它自己类型的对象,并且每个对象都有字符串字段名称,因为每个实例都有其自己的属性 –