如何使用GSON反序列化不同对象的数组
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用GSON反序列化不同对象的数组相关的知识,希望对你有一定的参考价值。
我收到这样的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"
}
]
当然,我实现了包含所有字段和类的Track,Album和Playlist类
Tracks {
String name;
List<Track> tracks;
}
Albums {
String name;
List<Album> albums;
}
Playlists {
String name;
List<Playlist> playlists;
}
我试图用以下方法对其进行反序列化:
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:预计BEGIN_OBJECT但是BEGIN_ARRAY在第1行第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):在android.os.ResultReceiver $ MyRunnable.run(ResultReceiver.java:43)11-20 19:24:55.210:E / AndroidRuntime(5432):在android.os.Handler.handleCallback(Handler.java:587)11- 20 19:24:55.210:E / AndroidRuntime(5432):在android.os.Handler.dispatchMessage(Handler.java:92)11-20 19:24:55.210:E / AndroidRuntime(5432):在android.os。 Looper.loop(Looper.java:130)11-20 19:24:55.210:E / AndroidRuntime(5432):在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 / And roidRuntime(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):引起:java.lang.IllegalStateException:预期BEGIN_OBJECT但是BEGIN_ARRAY在第1行第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个
附: json响应中的某些项可能会被遗漏。例如
[
{
"albums" : [
{"id":"0", "name":"name"},
{"id":"1", "name":"name"}
],
"name":"name"
}
]
那么问题是什么?如何反序列化这个JSON?
顺便说一句,我不能改变JSON。所以我需要一个解析它的代码。
这样做
你的数据
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"}]";
你的pojos
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);
}
谢谢大家的帮助!这是我的解决方案。
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;
}
最近我使用RuntimeTypeAdapterFactory用于相同的目的,它很容易是一个干净的解决方案。这是一个开放的Gson集成(额外)
查看这篇文章以查看和活动示例https://jansipke.nl/serialize-and-deserialize-a-list-of-polymorphic-objects-with-gson/我将原始代码从github直接导入到我的项目中(因为该类不直接拥有maven依赖项):
希望有帮助
您发布的JSON不显示JSONResponse对象数组,而是包含“专辑”,“曲目”和“播放列表”类型的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类,并在调用create()之前将其注册到GSONBuilder对象。
实际上你在JsonResponse课上犯了错误。
它清晰地形成了你的json格式,它从一个数组开始,而在JsonResponse类中你只是组成单个对象而不是对象的集合。如果你仔细看Gson异常为“BEGIN_OBJECT but was BEGIN_ARRAY
”。这意味着Gason的专辑,曲目和播放列表数组不是专辑,曲目和播放列表的对象。
您需要在JsonResponse类中进行一些更改,如下所示
private List<Albums> albums;
private List<Tracks> tracks;
private List<Playlists> playlists;
以上是关于如何使用GSON反序列化不同对象的数组的主要内容,如果未能解决你的问题,请参考以下文章