如何使用retroift2实现自定义的错误处理。

问题描述 投票:0回答:1

我调用api的基本改造。Call 对象。

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);

      }
  });

这里没什么特别的。

我对这种方法有几个问题

第一 - 例如,如果我给了错误的api键,响应应该给我一个包含问题代码的响应,而不是我只是得到null body。

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

我怎样才能实现自定义的错误处理,并适用于其他调用?

java error-handling retrofit retrofit2 retrofit2.6
1个回答
1
投票

我认为你可以使用 okhttp拦截器 并定义自己的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;
    }
};

define self ResponseBody converter

大多来自 com.squareup.retrofit2:转换器-jackon 我们只需添加两行。

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.