GSON反序列化忽略列表中的空对象

时间:2016-03-09 01:07:12

标签: java android json serialization gson

客户端决定开始在数组末尾发送空JSON个对象(以帮助他们缓存facepalm),但这在我的应用程序中引起了一大堆意外行为。

例如,这是我发送的数据......

[{object}, {object}, {}, {object}]

我目前使用GSON反序列化从服务器发送的数据。我一直在寻找类型适配器来过滤掉这些空对象,但是我不完全确定如何实现过滤。有关如何使用GSON跳过空对象的任何想法?

2 个答案:

答案 0 :(得分:2)

您可以从here

尝试此解决方案
class CollectionAdapter implements JsonSerializer<Collection<?>> {

     @Override
     public JsonElement serialize(Collection<?> src, Type typeOfSrc, JsonSerializationContext context) {
     if (src == null || src.isEmpty()) // exclusion is made here
        return null;

     JsonArray array = new JsonArray();

     for (Object child : src) {
         JsonElement element = context.serialize(child);
         array.add(element);
     }

     return array;
   }
}

然后注册

Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(Collection.class, new CollectionAdapter()).create();

答案 1 :(得分:2)

我解决了这个问题...我必须创建一个TypeAdapterFactory,将空对象设置为null,然后从结果列表中过滤掉空值。

这是我的TypeAdapterFactory

private static class EmptyCheckTypeAdapterFactory implements TypeAdapterFactory {

    @Override
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {

        // We filter out the EmptyCheckTypeAdapter as we need to check this for emptiness!
        if (Story.class.isAssignableFrom(type.getRawType())) {
            final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
            final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
            return new EmptyCheckTypeAdapter<>(delegate, elementAdapter).nullSafe();
        }
        return null;
    }

    public class EmptyCheckTypeAdapter<T> extends TypeAdapter<T> {

        private final TypeAdapter<T> delegate;
        private final TypeAdapter<JsonElement> elementAdapter;

        public EmptyCheckTypeAdapter(final TypeAdapter<T> delegate,
                                     final TypeAdapter<JsonElement> elementAdapter) {
            this.delegate = delegate;
            this.elementAdapter = elementAdapter;
        }

        @Override
        public void write(final JsonWriter out, final T value) throws IOException {
            this.delegate.write(out, value);
        }

        @Override
        public T read(final JsonReader in) throws IOException {
            final JsonObject asJsonObject = elementAdapter.read(in).getAsJsonObject();
            if (asJsonObject.entrySet().isEmpty()) {
                return null;
            }
            return this.delegate.fromJsonTree(asJsonObject);
        }
    }
}

最后,使用以下代码过滤掉null

myDto.stories.removeAll(Collections.singleton(null));