在反序列化时检查JSON输入的类型

时间:2017-05-28 12:28:28

标签: java android json gson

我可以从服务器收到2种不同类型的JSON。

例如我可能会得到:

{
 id:value,
 name:value,
 time:value
}

{
 id:value,
 name:value,
 image:value
}

有没有办法可以测试它来检查它是哪个JSON然后执行进一步的操作?

当前我正在使用GSON基于JSON输入创建对象。有没有办法让我可以使用GSON来获得这个功能?

2 个答案:

答案 0 :(得分:0)

假设您的JSON位于JsonObject中,您可以执行以下操作:

if (object.has("time")) {
  Time time = gson.fromJson(object, Time.class);
} else {
  Image image = gson.fromJson(object, Image.class);
}

答案 1 :(得分:0)

如果您不在反序列化环境中(在更多操作意义上,而不仅仅是gson.fromJson(...),在呼叫网站上),您可以使用jdebon的答案。如果您要在反序列化过程中检测到它,则可以创建自定义类型适配器(仅当您有一个公共基类时,但由于基本的Gson限制禁止绑定java.lang.Object)。例如:

private static final Gson gson = new GsonBuilder()
        .registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (jsonElement, type, context) -> {
            final JsonObject jsonObject = jsonElement.getAsJsonObject();
            final boolean hasImage = jsonObject.has("image");
            final boolean hasTime = jsonObject.has("time");
            if ( hasImage && hasTime ) {
                throw new JsonParseException("Cannot handle both image and time");
            }
            if ( hasImage ) {
                return context.deserialize(jsonElement, Image.class);
            }
            if ( hasTime ) {
                return context.deserialize(jsonElement, Time.class);
            }
            throw new JsonParseException("Cannot parse " + jsonElement);
        })
        .create();
abstract class Base {

    final int id = Integer.valueOf(0);
    final String name = null;

}
final class Image
        extends Base {

    final String image = null;

}
final class Time
        extends Base {

    final String time = null;

}

示例:

for ( final String resource : ImmutableList.of("image.json", "time.json") ) {
    try ( final JsonReader jsonReader = getPackageResourceJsonReader(Q44227327.class, resource) ) {
        final Base base = gson.fromJson(jsonReader, Base.class);
        System.out.println(base.getClass().getSimpleName());
    }
}

输出:

  

图像
  时间