繁体   English   中英

Retrofit 多种响应类型

[英]Retrofit multiple response types

我如何使用 Retrofit2 来解析这两种 API 响应?

好的响应(HTTP 200):

{
    "data": {
        "foo": "bar"
    }
}

错误响应(HTTP 200):

{
    "error": {
        "foo": "bar"
    }
}

我已经阅读了大量 SO 问题和教程,但我不知道该怎么做,我试过:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapterFactory(new ItemTypeAdapterFactory());
Gson gson = gsonBuilder.create();

final Retrofit retrofit = new Retrofit.Builder()
        .client(getOkHttpClient())
        .baseUrl(Constants.API_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build();

这是我的 ItemTypeAdapterFactory:

class ItemTypeAdapterFactory implements TypeAdapterFactory {

    public <T> TypeAdapter<T> create(final Gson gson, final 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();

                    // Data key
                    if (jsonObject.has(Constants.JSON_KEY_DATA)) {

                        JsonElement jsonData = jsonObject.get(Constants.JSON_KEY_DATA);

                        // Primitive
                        if (jsonData.isJsonPrimitive()) {
                            jsonElement = jsonData.getAsJsonPrimitive();
                        }
                        // JSON object
                        else if (jsonData.isJsonObject()) {
                            jsonElement = jsonData;
                        }
                        // JSON object array
                        else if (jsonData.isJsonArray()) {
                            jsonElement = jsonData.getAsJsonArray();
                        }
                    }
                }

                return delegate.fromJsonTree(jsonElement);
            }
        }.nullSafe();
    }
}

但是现在我不知道要在 retrofit2 接口上声明的类型,在 Call 中:

@GET("login")
Call<?> login(@Query(Constants.API_PARAM_TOKEN) String token);

你能给我指出正确的方向吗?

在类似的情况下,我曾经使用JsonObject作为类型,因此您的函数将如下所示:

@GET("login")
Call<?> login(@Query(Constants.API_PARAM_TOKEN) String token);

接下来,当您进行改造调用时,您将响应保留为字符串。 因此,在您的 Java 代码中,执行以下操作:

Call<JsonObject> call = RetrofitClient.getAPIService().login('YOUR_INPUT');
Data data = null;
Error error = null;
call.enqueue(new Callback<JsonObject>() {
            @Override
            public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if(response.isSuccessfull()){
  String jsonString = response.body().toString();
  if(jsonString.contains("data:")){
       data = new Gson().fromJson(jsonString,Data.class);
  }else{
      error = new Gson().fromJson(jsonString,Error.class);
  }
}
        }

在这里,我使用了DataError这两个类。 他们是 POJO。 所以数据看起来像这样:

Data.java

public class Data implements Serializable{
 @SerializedName("foo")
    @Expose
    private Foo foo; // Foo is your desired data type 

}

Error 因此,根据您的其余代码,进行必要的更改。 祝你好运。

我曾经做过这样的事情
基础反应

public class BaseResponse<D,E>{
E error;
D data;
public boolean isSuccess(){
    return error==null;
}

}

Retrofit接口

@GET("login")
Call<BaseResponse<LoginData,ErrorData>> login(@Query(Constants.API_PARAM_TOKEN) String token);

当您控制 REST API 结构时,此方法可以正常工作。
唯一的问题是在使用数据 object 之前,您需要为每个请求使用 isSuccess 方法检查是否成功。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM