Обработка несогласованного ответа API с помощью Retrofit - PullRequest
3 голосов
/ 17 июня 2020

У меня проблема в новом проекте. Я подключаюсь к API, который может отвечать двумя разными типами данных в одном ответе на основе некоторого лог-файла c сервера. Я использую Retrofit на Android, и мне было интересно, есть ли какой-нибудь «простой» способ справиться с этими случаями до анализа объекта модификации, например. какой-то парсер / сериализатор, который бы проверял, какой тип имеет поле c JSON? Я не знаю.

Вот возможные ответы:

ответ об ошибке:

{
  "ReturnCode": "error",
  "ReturnCodeNumber": 444,
  "ReturnMessage": "Invalid Request",
  "ReturnData": ""
}

ответ данных:

{
  "ReturnCode": "ok",
  "ReturnCodeNumber": 0,
  "ReturnMessage": "success",
  "ReturnData": [
    {

    }
  ]
}

Запрос на модернизацию API:

@FormUrlEncoded
@POST("url")
Observable<ApiResponse<List<Data>>> requestData()

Класс ответа API имеет открытые поля указанного выше ответа и параметризовал T для returnData.

Так можно ли как-то обернуть его в каком-то классе сериализатора?

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Попробуйте сделать, используя TypeAdapterFactory. Пример этого класса, как показано ниже.

public class ItemTypeAdapterFactory implements TypeAdapterFactory {
    @Override
    public <T> TypeAdapter<T> create(Gson gson, 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);
            }

            public T read(JsonReader in) throws IOException {
                JsonElement jsonElement = elementAdapter.read(in);
                if (jsonElement.isJsonObject()) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    if (jsonObject.has("data") && jsonObject.get("data").isJsonObject()) {
                        jsonElement = jsonObject.get("data");
                    }
                }
                return delegate.fromJsonTree(jsonElement);
            }
        }.nullSafe();
    }
}

И этот Gson в RestAdapter

final Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ItemTypeAdapterFactory()).create();
final Client client = new OkClient(new OkHttpClient());
final RestAdapter restAdapter = new RestAdapter.Builder().setClient(client).setLogLevel(RestAdapter.LogLevel.FULL).setConverter(new GsonConverter(gson)).setEndpoint(context.getString(R.string.base_url)).build();
0 голосов
/ 17 июня 2020

Вам нужно будет написать собственный десериализатор или зарегистрировать адаптер типа, как описано в этом -

https://sites.google.com/site/gson/gson-user-guide#TOC -Custom-Serialization-and-Deserialization

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...