Gson deserializer with Retrofit converter: just need inner JSON for all responses

android, gson, retrofit

Solution

With some help from Gowtham, I ended up doing the following:

private static class ItemTypeAdapterFactory implements TypeAdapterFactory {

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

        final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
        final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);

        return new TypeAdapter<T>() {
            @Override
            public void write(JsonWriter out, T value) throws IOException {
                delegate.write(out, value);
            }

            @Override
            public T read(JsonReader in) throws IOException {
                JsonElement jsonElement = elementAdapter.read(in);
                if (jsonElement.isJsonObject()) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    if (jsonObject.entrySet().size() == 2) {
                        jsonObject.remove("status");
                        jsonElement = jsonObject.entrySet().iterator().next().getValue();
                    }
                }
                return delegate.fromJsonTree(jsonElement);
            }
        }.nullSafe();
    }
}

and this is set on the RestAdapter.Builder:

.setConverter(new GsonConverter(new GsonBuilder()
                .registerTypeAdapterFactory(new ItemTypeAdapterFactory())
                .create()))

I really just ended up removing the "status" JsonObject.

Problem

I am working with an API that always responds like so: ``` { "stuff_i_need": [ { "title": "Hello" }, { "title": "World!" } ], "status": "success" } ``` and ``` { "other_things_key": { "version": "208" }, "status": "success" } ``` There are always two elements, and I just need the one that is not "status." I want to do this with one GsonBuilder, as well. I tried: ``` new GsonConverter(new GsonBuilder() .registerTypeAdapter(List.class, new JsonDeserializer<List>() { @Override public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { final JsonObject jsonObject = json.getAsJsonObject(); for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { final JsonElement element = entry.getValue(); if (element.isJsonArray()) { return new Gson().fromJson(element.getAsJsonArray(), new TypeToken<List>(){}.getType()); } } return null; } ) ``` but I don't think that is right, and it doens't satisfy the broader conditions.

Original source