Обрабатывать различные типы ответов JSON из одной конечной точки в RetroFit

мне нужна помощь.

у меня есть конечная точка, которая принимает параметр. В зависимости от этого параметра JSON возвращенный будет совершенно другим.

возможно RetroFit чтобы справиться с этим?

например:

http://myserver.com/all/<parameter>

где параметр BUS или BICYCLE, а также добавление других позже.

пример BUS запрос возвращает:

"stops": [{
    "Lat": "....",
    "Lng": "....",
    "Name": "Main Street",
    "Route": "",
    "StopNumber": "2"
}]

на BICYCLE конечная точка будет возвращение:

"stops": [{
    "address": "Town Centre",
    "lat": "....",
    "lng": "....",
    "number": "63",
    "open": "1"
}]

в зависимости от того, в каком разделе моего приложения для Android находится пользователь, я хотел бы отправить другой параметр и иметь возможность обрабатывать его с помощью того же вызова.

я думал об использовании родительского класса под названием AllTypes что каждый из других классов расширяется, а затем устанавливает мой Retrofit подпись вызова:

@GET("/all/{type}")
void getAll(@Path("type") String type, Callback<AllTypes> callback);

но я не уверен, если Retrofit может автоматически выбрать правильный класс ребенка для AllTypes на основе возвращенного JSON, или даже переданный параметр type.

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

спасибо.

3 ответов


просто чтобы закрыть это.

вы можете получить raw JSON обратно из RetroFit и использовать GSON чтобы вручную сериализовать тип класса, который вы хотите.

например:

RestClient.get().getDataFromServer(params, new Callback<JSONObject>() {
    @Override
    public void success(JSONObject json, Response response) {
        if(isTypeA) {
            //Use GSON to serialise to TypeA        
        } else {
            //Use GSON to serialise to TypeB
        }
    }
});

в этом ответе, так как это только изменения в полях, но не структуру как массив или объект. В этом случае просто определите все поля в объекте java, значения, которые будут возвращены в этом конкретном вызове, будут сопоставлены, а другие будут null. Положите логику на свой конец, чтобы проверить проверки null.


Вы можете использовать JsonElement в следующем : в Апиинтерфейсе.java:

@GET("web api url")
Call<JsonElement> GetAllMyClass();

чем в MyActivity :

ApiInterface client = ApiClient.getClient().create(ApiInterface.class);

    Call<JsonElement> call = client.GetAllMyClass();
    call.enqueue(new Callback<JsonElement>() {
       @Override
       public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
                if (response.isSuccessful()) {
                     JsonElement questions = response.body();

 // if response type is array
                     List<MyClass> response_array = new Gson().fromJson(((JsonArray)questions), new TypeToken<List<MyClass>>(){}.getType());

 // if response type is object
                     MyClass response_one = new Gson().fromJson(questions.getAsJsonObject(), MyClass.class);
                 } else {
                      Log.d("MyClassCallback", "Code: " + response.code() + " Message: " + response.message());
                        }
                    }

      @Override
      public void onFailure(Call<JsonElement> call, Throwable t) {
               t.printStackTrace();
       }
    });