Как вызвать десериализацию по умолчанию с помощью gson

Я получаю json с полем "поле".
Если в «поле» есть данные, то есть ОБЪЕКТ, у которого есть много (около 20) других полей, которые также являются объектами. Я могу десериализовать их без проблем.
Но если «поле» не имеет данных, это пустой МАССИВ (я знаю, что это сумасшествие, но это ответ сервера, и я не могу его изменить). Что-то вроде этого:

Когда пусто:

"extras":[

]

Имеет некоторые данные:

"extras": {
    "22":{ "name":"some name" },
    "59":{ "name":"some other name" },
    and so on...
}

Итак, когда нет данных (пустой массив), я, очевидно, получаю исключение

Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 4319

Я пытался использовать собственный JavaDeserializer:

public class ExtrasAdapter implements JsonDeserializer<Extras> {
    @Override
    public Extras deserialize(JsonElement json, Type typeOf,
        JsonDeserializationContext context) throws JsonParseException {
        try {
            JsonObject jsonObject = json.getAsJsonObject();
            // deserialize normally

            // the following does not work, as it makes recursive calls
            // to the same function
            //return context.deserialize(jsonObject,
            //                       new TypeToken<Object>(){}.getType());
        } catch (IllegalStateException e) {
            return null;
        }
    }
}

Я прочитал json следующим образом

Gson gsonDecoder = new GsonBuilder().registerTypeAdapter(Extras.class, new ExtrasAdapter();
// httpResponse contains json with extras filed. 
Reader reader = new InputStreamReader(httpResponse.getEntity().getContent());
Extras response = gsonDecoder.fromJson(reader, Extras.class);

Я не хочу десериализовать все 20 полей вручную (я знаю, что это вариант), я просто хочу вызвать context.defaultDeserialize() или что-то в этом роде.
Еще раз: у меня нет проблем с десериализацией обычного json, созданием пользовательских объектов, регистрацией пользовательских TypeAdapters, пользовательских JavaDeserializers. Все уже работает. Мне нужно только какое-то решение для обработки данных, которое может быть как МАССИВОМ, так и ОБЪЕКТОМ.
Спасибо за любую помощь.

======================


Ответ Джои работает отлично. Именно то, что я искал. Я опубликую свой код здесь.

public class SafeTypeAdapterFactory implements TypeAdapterFactory {
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
        return new TypeAdapter<T>() {
            public void write(JsonWriter out, T value) throws IOException {
                try {
                    delegate.write(out, value);
                } catch (IOException e) {
                    delegate.write(out, null);
                }
            }
            public T read(JsonReader in) throws IOException {
                try {
                    return delegate.read(in);
                } catch (IOException e) {
                    Log.w("Adapter Factory", "IOException. Value skipped");
                    in.skipValue();
                    return null;
                } catch (IllegalStateException e) {
                    Log.w("Adapter Factory", "IllegalStateException. Value skipped");
                    in.skipValue();
                    return null;
                } catch (JsonSyntaxException e) {
                    Log.w("Adapter Factory", "JsonSyntaxException. Value skipped");
                    in.skipValue();
                    return null;
                }
            }
        };
    }
}
28
задан Drakonoved 6 March 2018 в 14:04
поделиться