问题
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