【问题标题】:How to implement custom error handling with retroift2如何使用 retroift2 实现自定义错误处理
【发布时间】:2020-09-09 07:41:50
【问题描述】:

我用基本改造Call对象调用api:

public interface dataApi {
    @GET("animal/cats")
    Call<AllAnimals> getAllData(
            @Query("api_key") String apiKey
    );
}

我可以像这样在我的视图模型中得到响应:

  call.enqueue(new Callback<AllAnimals>() {

      @Override
      public void onResponse(Call<AllAnimals> call, Response<AllAnimals> response) {
          animals.setValue(response.body());
      }

      @Override
      public void onFailure(Call<AllAnimals> call, Throwable t) {
          Log.i(TAG, "onFailure: " + t);

      }
  });

这里没什么特别的。

我对这种方法有几个问题

FIRST - 例如,如果我提供了错误的 api 密钥,则响应应该给我一个带有问题代码的响应,而不是我只得到空正文。

第二次我计划进行更多的 api 调用,而且每次我编写的调用都要处理错误,这是一个巨大的代码重复。

如何针对这种情况实施自定义错误处理,这也将应用于其他调用?

【问题讨论】:

    标签: java error-handling retrofit retrofit2 retrofit2.6


    【解决方案1】:

    我认为您可以使用 okhttp interceptor 并定义自己的 ResponseBody 转换器来解决您的问题。

    • 首先,拦截您感兴趣的请求和响应;
    • 其次,检查响应,如果响应失败则修改响应体为空。

    定义一个简单的拦截器

    Interceptor interceptor = new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            String url = request.url().toString();
            System.out.println(request.url());
            okhttp3.Response response = chain.proceed(request);
    
            if (!response.isSuccessful() && url.contains("animal/cats")) {
                // request failed begin to modify response body
                response = response.newBuilder()
                    .body(ResponseBody.create(MediaType.parse("application/json"), new byte[] {}))
                    .build();
            }
    
            return response;
        }
    };
    

    定义自己的 ResponseBody 转换器

    com.squareup.retrofit2:converter-jackson 的大部分代码我们只添加了两行:

    final class JacksonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
        private final ObjectReader adapter;
    
        JacksonResponseBodyConverter(ObjectReader adapter) {
            this.adapter = adapter;
        }
    
        @Override public T convert(ResponseBody value) throws IOException {
            try {
                if (value.contentLength() == 0) {
                    return null;
                }
                return adapter.readValue(value.charStream());
            } finally {
                value.close();
            }
        }
    }
    

    添加如下代码:

    if (value.contentLength() == 0) {
        return null;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 2016-03-03
      • 2019-11-17
      • 2016-12-14
      • 2020-07-11
      • 2019-10-01
      相关资源
      最近更新 更多