Я хотел бы агностически получить дочерний элемент известного объекта JSON с каждым успешным ответом, который я получаю от конкретного API.
Каждый ответ сервера возвращает следующий формат JSON (сжатый для простоты):
{
"status": "success",
"error_title": "",
"error_message": "",
"data": {
"messages": [
{ "message_id": "123",
"content": "This is a message" },
{ "message_id": "124",
"content": "This is another message" }
]
}
}
Ответы об ошибках содержат один и тот же общий формат, при этом пустой объект "data" и связанные с ошибкой объекты JSON, содержащие полезные значения. В случае ошибки я хотел бы извлечь связанные с ошибкой объекты JSON.
С приведенным выше ответом у меня есть класс MessageResponse
, который содержит свойства статуса, errorTitle и errorMessage String, а также объект MessageData
. Затем объект MessageData
содержит список сообщений - List<Message> messages
. Мой метод GET для получения сообщений в этом случае выглядит следующим образом (сжатый для простоты):
@GET("/chat/conversation")
void getMessages(Callback<MessageResponse> callback);
Эта конструкция требует трех классов для каждого типа ответа, если я должен придерживаться стандартного POJO-сопоставления, которое Serializer GSON предоставляет из коробки. Моя конечная цель - сократить количество классов, необходимых, читая только то, что мне нужно, от успешного ответа сервера и игнорируя остальные. Я хотел бы, чтобы все мои успехи, типы данных обратного вызова в этом API были как можно ближе к содержанию "данных".
Другими словами, я хотел бы агностически вернуть дочерний элемент "данных". В приведенном выше случае это массив, называемый "сообщениями", но в некоторых других ответах он может быть, например, "пользовательским" объектом. Я знаю, что это можно сделать, зарегистрировав отдельный TypeAdapter
для каждого типа ответа, но я хотел бы достичь своей конечной цели, используя одно общее решение.
ОБНОВЛЕНИЕ: реализация предложения Дэвида снизу
public class BaseResponse<T> {
@SerializedName("status") public String status;
@SerializedName("error_title") public String errorMessageTitle;
@SerializedName("error_message") public String errorMessage;
@SerializedName("data") public T data;
}
public class MessagesResponse extends BaseResponseData<List<Message>> {
@SerializedName("messages") List<Message> messages;
}
@GET("/chat/conversation")
void getMessages(Callback<BaseResponse<MessageResponse>> callback);
К сожалению, это не правильно сериализовано. Если бы я мог каким-то образом сообщить GSON о дочернем объекте с переменным именем JSON из родителя "data" и десериализовать этот дочерний элемент в класс модели, на который ссылается общий тип данных. По существу, dataJsonObject.getChild()
.