Retrofit: Deserializing list of objects into different types

房东的猫 提交于 2019-12-11 00:45:17

问题


Developing Android application. I'm using retrofit to get my response. Currently I have made one POJO model class, which contains fields from all types (In reality they have way more fields and their own methods, so I have simplified them here a lot).

Code from Client.class:

    OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.readTimeout(30, TimeUnit.SECONDS);
    OkHttpClient okHttpClient = builder.build;
    Retrofit retrofit = new Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .client(okHttpClient)
        .build();

What I would like to achieve is specific models for all types (Taxi.class and Van.class) that are extending baseclass Car.class

Currently my Car.class looks like this:

public class Car {
    public String type;
    public String id;
    public boolean isClean;
    public int seats;
    public int fuelTankCapacity;
}

But I would like to have Car, Van and Taxi models like this:

public class Car {
    public String type;
    public String id;
}

public class Van extends Car {
    public int fuelTankCapacity;
}

public class Taxi extends Car {
    public boolean isClean;
    public int seats;
}

Response from server (JSON):

    {
    "items": [{
            "type": "taxi",
            "id": "1i2ilkad2",
            "isClean": "true",
            "seats": "5"
        },
        {
            "type": "van",
            "id": "aopks21k",
            "fuelTankCapacity": 76
        }, etc...
    ]
}

I have understood that it should be done somehow with adding additional lines like .addConverterFactory(new CarJSONConverter()) to retrofit instance, but I have no idea how should I implement this converter..


回答1:


Crate your custom serialize/deserialize like this:

static class CarDeserializer implements JsonDeserializer<Car> {

        @Override
        public Car deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            JsonObject obj = json.getAsJsonObject();
            String type = obj.get("type").getAsString();
            if (type.equalsIgnoreCase("van")) {
                // return van
            } else {
                // return taxe
            }
            return null;
        }
    }

    static class CarSerializer implements JsonSerializer<Car> {

        @Override
        public JsonElement serialize(Car src, Type typeOfSrc, JsonSerializationContext context) {
            JsonObject obj = new JsonObject();
            if (src instanceof Taxi) {
                // code here
            } else if (src instanceof Van) {
                // code here
            }
            return obj;
        }
    }

Create gson with custom serializer/deserializer

  Gson getGson() {
        return new GsonBuilder().registerTypeAdapter(Car.class, new CarDeserializer())
                .registerTypeAdapter(Car.class, new CarSerializer()).create();
    }

Ask retrofit to use that gson:

  Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(getGson()))
            .build();


来源:https://stackoverflow.com/questions/46969104/retrofit-deserializing-list-of-objects-into-different-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!