【问题标题】:Retrofit / OkHttp3 400 Error Body Empty改造/OkHttp3 400 错误正文为空
【发布时间】:2016-11-17 21:55:53
【问题描述】:

我在我的 Android 项目中使用 Retrofit 2。当我使用 GET 方法访问 API 端点并返回 400 级错误时,我可以在使用 HttpLoggingInterceptor 时看到错误内容,但是当我到达 Retrofit OnResponse 回调时,错误正文的字符串为空。

我可以看到错误有一个正文,但是在 Retrofit 回调的上下文中我似乎无法拉出该正文。有没有办法确保在那里可以接触到尸体?

谢谢, 亚当

编辑: 我从服务器看到的响应是: {"error":{"errorMessage":"对于输入字符串:\"000001280_713870281\"","httpStatus":400}}

我正在尝试通过以下方式从响应中提取该响应: BaseResponse baseResponse = GsonHelper.getObject(BaseResponse.class, response.errorBody().string()); if (baseResponse != null && !TextUtils.isEmpty(baseResponse.getErrorMessage())) error = baseResponse.getErrorMessage();

(GsonHelper 只是一个帮助器,它通过 GSON 传递 JSON 字符串以提取 BaseResponse 类型的对象)

对 response.errorBody().string() 的调用导致 IOException:Content-Length 和流长度不一致,但我在 Log Cat 中看到上面两行的内容

【问题讨论】:

  • 你可以发布你的示例代码来尝试访问正文
  • 您找到解决此问题的方法了吗?我正在努力解决同样的问题,我可以在日志中看到错误响应正文,但 errorBody 内容为空。
  • 我没有。我只是在一般意义上处理来自我的 API 的任何错误,而不是向用户显示有意义的错误。这并不理想,但在我理解为什么 Retrofit / OkHttp 正在剥离错误信息之前,我看到的唯一选择。
  • adamacdo,您的问题解决了吗?我有同样的问题..非常感谢你
  • 我没有。那是为了一个我后来离开的项目。我显示了一个通用错误,而没有来自服务器的实际错误作为解决方法。没有帮助,但总比没有好。

标签: android retrofit2 okhttp3


【解决方案1】:

如果您是 gettig 400,那么它是您尝试发送到服务器的错误请求。 检查你的获取请求。

【讨论】:

  • 这是有道理的,但我想从返回的错误中提取错误正文以提示我的用户。当我收到 500 级错误时,我看到也返回了错误正文。无论错误如何,我都想显示任何错误正文,即使错误是由于请求格式不正确造成的。
【解决方案2】:

我之前遇到过同样的问题,我通过使用代码response.errorBody().string() only修复了它。如果您多次使用它,您将收到 IOException,因此建议您将其用作一次性流,就像 ResponseBody 上的文档所说的那样。

我的建议是:立即将 Stringified errorBody() 转换为 Object,因为后者是您将在后续操作中使用的。

【讨论】:

    【解决方案3】:

    首先创建一个如下所示的错误类:

    public class ApiError {
        @SerializedName("httpStatus")
        private int statusCode;
        @SerializedName("errorMessage")
        private String message;
    
        public ApiError() {
    
        }
    
        public ApiError(String message) {
            this.message = message;
        }
    
        public ApiError(int statusCode, String message) {
            this.statusCode = statusCode;
            this.message = message;
        }
    
        public int status() {
            return statusCode;
        }
    
        public String message() {
            return message;
        }
    
        public void setStatusCode(int statusCode) {
            this.statusCode = statusCode;
        }
    }
    

    其次,您可以创建一个 Utils 类来处理您的错误,如下所示:

    public final class ErrorUtils {
        private ErrorUtils() {
    
        }
    
        public static ApiError parseApiError(Response<?> response) {
            final Converter<ResponseBody, ApiError> converter =
                    YourApiProvider.getInstance().getRetrofit()
                            .responseBodyConverter(ApiError.class, new Annotation[0]);
    
            ApiError error;
            try {
                error = converter.convert(response.errorBody());
            } catch (IOException e) {
                error = new ApiError(0, "Unknown error"
            }
            return error;
        }
    

    最后像下面这样处理你的错误:

    if (response.isSuccessful()) {
       // Your response is successfull
       callback.onSuccess();
       } 
    else {
       callback.onFail(ErrorUtils.parseApiError(response));
       }
    

    我希望这会对你有所帮助。祝你好运。

    【讨论】:

      猜你喜欢
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 2016-05-30
      • 1970-01-01
      • 2016-03-02
      • 2017-09-18
      相关资源
      最近更新 更多