Gson处理对象或数组

thr*_*ups 46 gson

我有以下课程

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

public class MyOtherClass {
    private String name;
}
Run Code Online (Sandbox Code Playgroud)

我有JSON可能看起来像这样

{
  others: {
    name: "val"
  }
}
Run Code Online (Sandbox Code Playgroud)

或这个

{
  others: [
    {
      name: "val"
    },
    {
      name: "val"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我希望能够MyClass对这两种JSON格式使用相同的格式.有没有办法用Gson做到这一点?

thr*_*ups 77

我想出了一个答案.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样实例化一个Gson对象

Type myOtherClassListType = new TypeToken<List<MyOtherClass>>() {}.getType();

Gson gson = new GsonBuilder()
        .registerTypeAdapter(myOtherClassListType, new MyOtherClassTypeAdapter())
        .create();
Run Code Online (Sandbox Code Playgroud)

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

你可以在这里阅读解决方案:

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

  • 为什么Gson不只是将注释放在接受相同格式的数组或对象上?这是非常需要的. (6认同)

lev*_*are 9

谢谢三杯解决方案!

如果需要多种类型,请使用泛型类型:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

并配置Gson:

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