Как прокомментировал @Ridcully, это плохой дизайн API.Поскольку вы не можете изменить API, в качестве обходного пути можно использовать наследование и добавление пользовательского typeAdapter
к экземпляру Gson.
Обратите внимание, что SuccessResponse
и FailureResponse
"is-a" Response
.Когда вы используете typeAdapter для класса Response
, пользовательский десериализатор будет определять, следует ли десериализовать объект в класс SuccessResponse
или FailureResponse
, основываясь на значении Response.meta.status
.
Родительский класс ответа
public class Response{
private Meta meta;
public Meta getMeta(){ return meta; }
public void setMeta(Meta meta){ this.meta = meta; }
}
Дочерний класс ответа ответа
public class SuccessResponse extends Response{
private SuccessContent body;
public SuccessContent getSuccessContent() { return body; }
public void setSuccessContent(SuccessContent content) { this.body = content }
}
Дочерний класс ответа отказа
public class FailureResponse extends Response{
private List<FailureContent> body;
public List<FailureContent> getBody() { return body; }
public void setObjList(List<FailureContent> content) { this.body= content; }
}
Класс содержимого успеха
public class SucessContent{
//Model class of the success body
}
Класс содержимого ошибки
public class FailureContent{
private String errorCode;
private String errorMessage;
private String property;
private String args;
public String getErrorCode() { return errorCode; }
public void setErrorCode(String errorCode) { this.errorCode = errorCode; }
public String getErrorMessage() { return errorMessage; }
public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage;}
public String getProperty() { return property; }
public void setProperty(String property) { this.property = property; }
public String getArgs() { return args; }
public void setArgs(String args) { this.args = args; }
}
Meta Class
public class Meta{
private String timestamp;
private String status;
public String getTimestamp() { return this.timestamp; }
public void setTimestamp(String timestamp) { this.timestamp = timestamp; }
public String getStatus() { return this.status; }
public void setStatus(String status) { this.status = status; }
}
Адаптер пользовательского типа Gson для десериализации Класс ответа
public class ResponseBodyAdapter implements JsonDeserializer<Response> {
@Override
public Response deserialize (JsonElement json, Type typeOfT, JsonDerializationContext context) throws JsonParseException{
JsonObject obj = json.getAsJsonObject();
JsonObject metaObj = obj.getAsJsonObject("meta");
String status = metaObj.get("status").getAsString();
if(status.equals("OK")){
return context.deserialize(json, SuccessResponse.class);
}else if(status.equals("VALIDATION_ERROR")){
return context.deserialize(json, FailureResponse.class);
}
return null;
}
}
Регистрация адаптера типа в gson и длядооснащение
Gson gson = new GsonBuilder()
.registerTypeAdapter(Response.class, new ResponseBodyAdapter ())
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();