【问题标题】:Retrofit 2 does not parse response in case error如果出现错误,Retrofit 2 不会解析响应
【发布时间】:2016-07-06 09:20:02
【问题描述】:

我在我的项目中使用 Retrofit 2。 我对以下情况有疑问。

当我打电话给APIserver 时,告诉我带有error code 的request was not executed4xx500,并带有问题的详细信息。

但似乎retrofit 明白这是一个http error 并且没有从Server 收集error message

我看到了同样的问题here,但它没有解决我的问题。

我完全得到响应成功,我确信我的实施没有问题。

    @Override
    public void onResponse(Response<CustomResponse> response, Retrofit retrofit) {
    Log.d("Response : ", response.body(), response.code()); // here i got response.body() is null if response code is not 200, if response code is 200 -- it work well as I expected.
    onRequestSuccess(response);
}

我查看了retrofit 中的Response 类,我看到以下代码:

  private Response(com.squareup.okhttp.Response rawResponse, T body, ResponseBody errorBody) {
       this.rawResponse = checkNotNull(rawResponse, "rawResponse == null");
       this.body = body;
       this.errorBody = errorBody;
  }

还有

  public static <T> Response<T> error(ResponseBody body, com.squareup.okhttp.Response rawResponse) {
      return new Response<>(rawResponse, null, body);
  }

似乎当server中的response代码不是200时,retrofit明白这是错误并将body设置为null

那么在这种情况下,任何人都可以帮助获得response body 的“正确”值吗?

【问题讨论】:

  • 只需使用 response.errorBody()
  • 这没有帮助。 response.Body().string() = ""

标签: android retrofit okhttp retrofit2


【解决方案1】:

使用类似的东西:

if(response.isSuccessful()){
    response.body()
} else{
    response.errorBody()
}

【讨论】:

【解决方案2】:

当服务器的响应不正确时,您必须捕获错误正文并将其解析为您的 errorModel。例如:

try {
        // call to retrofit
        Response<SimpleAnswerModel> response = call.execute();
        if (response.isSuccess()) {
            // Do something interesting
        } else {
            Converter<ResponseBody, ErrorModel> converter = apiService.getRetrofit().responseBodyConverter(ErrorModel.class, new Annotation[0]);
            ErrorModel errorModel = converter.convert(response.errorBody());
            // it fails!
            resetNewAlarm();
        }

    } catch (Exception e) {
        // connection fails!
        resetNewAlarm();
    }

【讨论】:

  • 导入 okhttp3.ResponseBody;导入 retrofit2.Call;导入 retrofit2.Converter;导入 retrofit2.Response;
【解决方案3】:

尝试像这样解析响应:

@Override
            public void onResponse(Call<Void> call, Response<Void> response) {
                //hideLoadingDialog();
                if (response.isSuccess()) {

                    Toast.makeText(ProximityFeedbackActivity.this, "Feedback successfully sent", Toast.LENGTH_LONG).show();
                }

            }

            @Override
            public void onFailure(Call<Void> call, Throwable t) {
                //hideLoadingDialog();
                ProximityFeedbackActivity.this.finish();
                startThankYouActivity();
                Log.e(TAG, "Error in Feedback submission " + t.getMessage());
            }

【讨论】:

  • 你的意思是我可以使用 Void 类型来响应?
  • 是的,你可以@Phan Dinh Thai
【解决方案4】:

正如其他人所说的

if(response.isSuccessful()){
    response.body()
} else{
    response.errorBody()
}

是处理错误的正确方法。

string() 方法中调用了readString 方法

  /** Removes all bytes from this, decodes them as {@code charset}, and returns the string. */
  String readString(Charset charset) throws IOException;

基于注释response.errorBody().string() 将在您第一次调用它时返回错误。连续调用将返回一个空字符串。

即使您的代码中没有调用,但您有一个断点,然后您检查 string() 的值,它也会为空。

【讨论】:

  • 但是将errorBody归零似乎很奇怪,因为它只返回一次字符串。看起来像是一条读完后就会燃烧的间谍信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多