[英]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);
}
}
}
在這里,我使用了Data
和Error
這兩個類。 他們是 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.