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);