【问题标题】:Handle different JSON response types from same endpoint in RetroFit在 RetroFit 中处理来自同一端点的不同 JSON 响应类型
【发布时间】:2016-02-13 15:25:39
【问题描述】:

我需要帮助。

我有一个带有参数的端点。根据这个参数,返回的JSON会完全不同。

RetroFit 可以处理吗?

例如:

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

其中参数为BUSBICYCLE,以及稍后添加其他。

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是否可以根据返回的JSON,甚至是传递的参数type,自动为AllTypes选择正确的子类。

有人知道怎么做吗? 如果没有,我只需要创建多个具有不同回调类型的不同方法。

谢谢。

【问题讨论】:

  • 最好将JSON 合并为一个并为特定类型设置参数
  • 你的意思是有一个大类,其中包含来自所有不同JSON 响应的所有字段?这可能效率低下。
  • 我的意思是让一个 General JSON 类两种类型都使用那个
  • 会有2种以上。至少 4 个。
  • 我刚想到一个主意。我可能只返回一个JSONObject 并使用GSON 自己转换为我的首选选项。当我调用端点时,我会知道我需要哪种类型,这样可能更有意义。

标签: android json retrofit


【解决方案1】:

只是为了关闭它。

您可以从 RetroFit 获取原始 JSON 并使用 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
        }
    }
});

【讨论】:

    【解决方案2】:

    你可以使用 JsonElement 如下: 在 ApiInterface.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();
           }
        });
    

    【讨论】:

      【解决方案3】:

      我知道这有点晚了,但我的提示可能对某人有用。

      如果返回的 JSON 内容取决于端点参数“类型”(例如),则可以使用 Moshi 中的 PolymorphicJsonAdapterFactory 解码到某个类。请注意返回的 JSON 必须包含类型信息。

      【讨论】:

        【解决方案4】:

        在这个响应中,因为它只是字段的变化,而不是像数组或对象这样的结构。 在这种情况下,只需定义 java 对象中的所有字段,将在该特定调用中返回的值将被映射,其他值将为 null。在你的最后加上一个逻辑来检查空检查。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-22
          • 2016-06-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多