2016-03-09 4 views
1

Клиент решил начать отправку пустых JSON объектов в конце массивов (чтобы помочь их кешировать facepalm), но это вызвало целую кучу неожиданного поведения в моем приложении.GSON deserialization игнорирует пустые объекты в списке

Например, это данные я посылаю ...

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

Я в настоящее время использую GSON десериализацию данные, отправленные с сервера. Я искал типы адаптеров для фильтрации этих пустых объектов, однако я не совсем уверен, как реализовать фильтрацию. Любые идеи о том, как пропустить пустые объекты с помощью GSON?

+1

У вас возникли проблемы с фактической десериализации, или вы возникли проблемы после разбора полный и объекты были созданы? –

+0

Разбор был прав ... Я просто задавался вопросом, есть ли способ легко игнорировать пустые объекты .... – fergdev

+1

Можете ли вы просто перебрать полученные объекты и удалить те, у которых отсутствуют данные? –

ответ

4

Вы можете попробовать это решение от 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(); 
+2

Мне не нужно сериализовать данные ... могу ли я сделать что-то подобное для десериализации? – fergdev

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)); 
Смежные вопросы