【问题标题】:Retrofit2, how to convert response to base class?Retrofit2,如何将响应转换为基类?
【发布时间】:2016-05-26 08:07:32
【问题描述】:

我的回复有基类。当出现问题(例如身份验证问题)时会调用此类。

public class DefaultResponse
{
    private transient Integer status;
    private String            property;
    private String            message;
    private String            developerMessage;
    protected String          code;

    public void setResponse(final Response response)
    {
        if (this.status != null)
        {
            return;
        }

        if (response != null)
        {
            try
            {
                final Object obj = response.body();
                if (obj != null && obj instanceof DefaultResponse)
                {
                    this.status = response.code();
                    this.message = ((DefaultResponse) obj).message;
                    this.developerMessage = ((DefaultResponse) obj).developerMessage;
                    this.property = ((DefaultResponse) obj).property;
                    this.code = ((DefaultResponse) obj).code;
                }
            }
            catch (final Exception ignored)
            {

            }
        }
    }

...
}

其余的 Responses 正在扩展这个类。

public class FeatureResponse extends DefaultResponse 
{
    // Implementation
}

这是我用来调用 API 以获取功能的方法。

    public void getFeatures(final Location location)
    {
        Call<FeatureResponse> call = mService.getPassengerFeatures(location);
        call.enqueue(new Callback<FeatureResponse>()
        {
            @Override
            public void onResponse(Call<FeatureResponse> call, Response<FeatureResponse> response)
            {
                Logger.debug("Test", "Instance of response: " + response.getClass());

                FeatureResponse featureResponse = new FeatureResponse();

                if (response.isSuccessful())
                {
                    //...
                }

                featureResponse.setResponse(response);
                EventBus.post(featureResponse);
            }

            @Override
            public void onFailure(Call<FeatureResponse> call, Throwable t)
            {
                Logger.error(TAG, "getPassengerFeatures.onFailure(), msg: " + t.getMessage());

                FeatureResponse featureResponse = new FeatureResponse();
                featureResponse.setFailure(t);
                EventBus.post(featureResponse);
            }
        });
    }

当我发送请求时,这是我的服务器响应:

{"status":403,"code":4030,"property":"","message":"Unauthorized access","developerMessage":"Unauthorized access"}

因此,onResponse 被调用,FeatureResponse 的新对象被创建,featureResponse.setResponse(response); 被调用。正如您在上面的代码中看到的,我正在尝试获取其 HTTP 状态代码。但是,问题是 if (obj != null &amp;&amp; obj instanceof DefaultResponse) 始终是 false,因为 response 是类 retrofit2.Response 的实例。

是否可以将Response 转换为DefaultResponse

【问题讨论】:

    标签: android retrofit2


    【解决方案1】:

    当我收到诸如 401 、 400 之类的错误时,使用 Gson 的这种方式:

    if (response.code() == 400) 
    {
       Gson gson = new GsonBuilder().create();
       MyPojoError myPojoError=new MyPojoError ();
       try {
             myPojoError= gson.fromJson(response.errorBody().string(),MyPojoError .class);
            } catch (IOException e) {  // handle failure to read error   }
    
    }
    

    在使用Gson 将响应转换为Pojo 时,您还需要注释:

    public class MyPojoError {
    
    @SerializedName("error")
    @Expose
    private String error;
    @SerializedName("error_description")
    @Expose
    private String errorDescription;
    
    /**
     *
     * @return
     * The error
     */
    public String getError() {
        return error;
    }
    
    /**
     *
     * @param error
     * The error
     */
    public void setError(String error) {
        this.error = error;
    }
    
    /**
     *
     * @return
     * The errorDescription
     */
    public String getErrorDescription() {
        return errorDescription;
    }
    
    /**
     *
     * @param errorDescription
     * The error_description
     */
    public void setErrorDescription(String errorDescription) {
        this.errorDescription = errorDescription;
    }
    
    }
    

    将您的示例Json 响应粘贴到站点,选择源类型JSON,注释:GsonJson Schema to Pojo

    在您的 build.gradle 中:compile 'com.google.code.gson:gson:2.6.2'

    【讨论】:

    • 很棒的兄弟,很有帮助。我的另一个问题是status 设置为瞬态(来自以前的版本)。我改变了它,现在我解析服务器响应。谢谢。
    • 不客气,很高兴解决您的问题。祝你有美好的一天:)
    猜你喜欢
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 2015-08-29
    • 2016-11-21
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多