Обрабатывать различные типы ответов 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();
       }
    });
