我们如何使用Retrofit 2处理不同的响应类型? [英] How can we handle different response type with Retrofit 2?

查看:293
本文介绍了我们如何使用Retrofit 2处理不同的响应类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web服务,该服务返回一个序列化的MyPOJO对象的列表:

I have a webservice that returns either a list of serialized MyPOJO objects:

[
  { //JSON MyPOJO },
  { //JSON MyPOJO }
]

两个错误对象:

{  
  'error': 'foo', 
  'message':'bar' 
}

使用retrofit2,如何检索错误?

Using retrofit2, how can I retrieve the error ?

Call<List<MyPOJO>> request = ...
request.enqueue(new Callback<List<MyPOJO>>() {
  @Override
  public void onResponse(Response<List<MyPOJO>> response) {
      if (response.isSuccess()) {
          List<MyPOJO> myList = response.body();
          // do something with the list...
      } else {
          // server responded with an error, here is how we are supposed to retrieve it
          ErrorResponse error = ErrorResponse.fromResponseBody(apiService.getRetrofitInstance(), response.errorBody());
          processError(error);
          // but we never get there because GSON deserialization throws an error !
      }
  }

  @Override
  public void onFailure(Throwable t) {
    if(t instanceof IOException){
        // network error 
    }else if(t instanceof IllegalStateException){
        // on server sending an error object we get there
        // how can I retrieve the error object ?
    }else { 
        // default error handling 
    }       
  }
}

这是GSON例外:

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Retrofit实例是使用GsonConverterFactory创建的

Retrofit instance is created using GsonConverterFactory

推荐答案

我遇到了类似的问题,我使用通用的Object解决了该问题,然后使用instanceof

I had a similar issue and I solved it by using a generic Object and then testing what type of response I had using instanceof

Call<Object> call = api.login(username, password);
call.enqueue(new Callback<Object>() 
{
    @Override
    public void onResponse(Response<Object> response, Retrofit retrofit)
    {
         if (response.body() instanceof MyPOJO )
         {
            MyPOJO myObj = (MyPOJO) response.body();
            //handle MyPOJO 
         }
         else  //must be error object
         {
            MyError myError = (MyError) response.body();
            //handle error object
         }
    }

    @Override
    public void onFailure(Throwable t) 
    {
     ///Handle failure
    }
});

在我的情况下,我返回了MyPOJO或MyError,并且可以确定它就是其中之一.

In my case I had either MyPOJO or MyError returned and I could be sure it would be one of these.

在其他情况下,无论请求是否成功,后端都将返回相同的Response Object.
然后,在此响应对象中,我将实际数据存储在对象"字段中.然后,我可以使用的实例来确定我拥有的数据类型.在这种情况下,无论调用是什么,我总是会返回相同的对象.

In other cases then I had the backend return the same Response Object no matter if the request was successful or not.
Then inside this response object I had my actual data within an "Object" field. Then I can use instance of to determine what type of data I had. In this case I always had the same object being returned, no matter what the call was.

public class MyResponse {

    private int responseCode;
    private String command;
    private int errorno;
    private String errorMessage;
    private Object responseObject;   //This object varies depending on what command was called
    private Date responseTime;
}

这篇关于我们如何使用Retrofit 2处理不同的响应类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆