D
D
Daniil Miroshnichenko2015-06-10 16:25:56
Java
Daniil Miroshnichenko, 2015-06-10 16:25:56

How to parse complex json files using Gson and TypeAdapterFactory?

Hello.
I am developing a rest application on Android. I use Retrofit + Gson + RxJava.
The following responses come from the server:

{"error":false,"json":true,"body":{...JSON object...}}

You should always parse what's in body.
I tried to create my own TypeAdapterFactory and this is what happened:
public class ItemTypeAdapterFactory implements TypeAdapterFactory {

    public static final String BODY = "body";

    @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>() {

            public void write(JsonWriter out, T value) throws IOException {
                delegate.write(out, value);
                Logger.d(this, "dami");
            }

            public T read(JsonReader in) throws IOException {
                JsonElement jsonElement = elementAdapter.read(in);
                if (jsonElement.isJsonObject()) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    if (jsonObject.has(BODY) && jsonObject.get(BODY).isJsonObject()) {
                        jsonElement = jsonObject.get(BODY);
                    }
                }

                return delegate.fromJsonTree(jsonElement);
            }
        }.nullSafe();
    }

Next, we use this in creating the retrofit service:
public abstract class AbstractApiService {
    private RestAdapter restAdapter;

    public AbstractApiService() {
        Gson gson = new GsonBuilder()
                .registerTypeAdapterFactory(new ItemTypeAdapterFactory())
                .create();

        restAdapter = new RestAdapter.Builder()
                .setEndpoint(ApiConf.API_URL)
                .setConverter(new GsonConverter(gson))
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
    }

    protected <T> T create(Class<T> service) {
        return restAdapter.create(service);
    }
}

The result is that it never even gets into the create method of the ItemTypeAdapterFactory and, apparently, Gson continues to use its standard implementation.
Help me please.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
dmolokanov, 2015-06-11
@dmolokanov

If I'm not mistaken, in order for parsing to work, you must explicitly tell GSON what type of object to parse. Otherwise, he does not know why he should parse with the specified parser. But I really didn't use retrofit.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question