Gson处理对象或数组

我有以下课程

public class MyClass { private List<MyOtherClass> others; } public class MyOtherClass { private String name; } 

我有JSON可能看起来像这样

 { others: { name: "val" } } 

或这个

 { others: [ { name: "val" }, { name: "val" } ] } 

我希望能够使用这两个这些JSON格式相同的MyClass 。 有没有办法与Gson做到这一点?

我想出了一个答案。

 private static class MyOtherClassTypeAdapter implements JsonDeserializer<List<MyOtherClass>> { public List<MyOtherClass> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) { List<MyOtherClass> vals = new ArrayList<MyOtherClass>(); if (json.isJsonArray()) { for (JsonElement e : json.getAsJsonArray()) { vals.add((MyOtherClass) ctx.deserialize(e, MyOtherClass.class)); } } else if (json.isJsonObject()) { vals.add((MyOtherClass) ctx.deserialize(json, MyOtherClass.class)); } else { throw new RuntimeException("Unexpected JSON type: " + json.getClass()); } return vals; } } 

像这样实例化一个Gson对象

 Type myOtherClassListType = new TypeToken<List<MyOtherClass>>() {}.getType(); Gson gson = new GsonBuilder() .registerTypeAdapter(myOtherClassListType, new MyOtherClassTypeAdapter()) .create(); 

TypeToken是一个com.google.gson.reflect.TypeToken

你可以在这里阅读有关解决scheme:

https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Gener

谢谢三杯的解决scheme!

如果需要多种types,则使用genericstypes:

 public class SingleElementToListDeserializer<T> implements JsonDeserializer<List<T>> { private final Class<T> clazz; public SingleElementToListDeserializer(Class<T> clazz) { this.clazz = clazz; } public List<T> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { List<T> resultList = new ArrayList<>(); if (json.isJsonArray()) { for (JsonElement e : json.getAsJsonArray()) { resultList.add(context.<T>deserialize(e, clazz)); } } else if (json.isJsonObject()) { resultList.add(context.<T>deserialize(json, clazz)); } else { throw new RuntimeException("Unexpected JSON type: " + json.getClass()); } return resultList; } } 

并configurationGson:

 Type myOtherClassListType = new TypeToken<List<MyOtherClass>>() {}.getType(); SingleElementToListDeserializer<MyOtherClass> adapter = new SingleElementToListDeserializer<>(MyOtherClass.class); Gson gson = new GsonBuilder() .registerTypeAdapter(myOtherClassListType, adapter) .create(); 

build立三杯的答案,我有以下让JsonArray直接作为数组反序列化。

 static public <T> T[] fromJsonAsArray(Gson gson, JsonElement json, Class<T> tClass, Class<T[]> tArrClass) throws JsonParseException { T[] arr; if(json.isJsonObject()){ //noinspection unchecked arr = (T[]) Array.newInstance(tClass, 1); arr[0] = gson.fromJson(json, tClass); }else if(json.isJsonArray()){ arr = gson.fromJson(json, tArrClass); }else{ throw new RuntimeException("Unexpected JSON type: " + json.getClass()); } return arr; } 

用法:

  String response = "......."; JsonParser p = new JsonParser(); JsonElement json = p.parse(response); Gson gson = new Gson(); MyQuote[] quotes = GsonUtils.fromJsonAsArray(gson, json, MyQuote.class, MyQuote[].class);