针对 4xx 错误的 Retrofit 2 同步调用错误处理

Retrofit 2 synchronous call error handling for 4xx Errors

我正在使用 android-priority-jobqueue 并且我使用 retrofit 对我的 rest 进行同步调用 api 但我不确定如何处理像 401 Unauthorized errors 这样的错误,我发回 json 说明错误。进行异步调用时很简单,但我正在为作业管理器调整我的应用程序。下面是 IO 异常的简单尝试捕获,但是 401 的 422 等?如何做到这一点?

try {
    PostService postService = ServiceGenerator.createService(PostService.class);
    final Call<Post> call = postService.addPost(post);
    Post newPost = call.execute().body();

    // omitted code here

} catch (IOException e) {
    // handle error
}

编辑

改装响应对象的使用对我来说是决定性因素,返回改装响应对象让我能够

Response<Post> response = call.execute();

if (response.isSuccessful()) {
    // request successful (status code 200, 201)
    Post result = response.body();

    // publish the post added event
    EventBus.getDefault().post(new PostAddedEvent(result));
} else {
    // request not successful (like 400,401,403 etc and 5xx)
    renderApiError(response);
}

检查响应代码并显示相应的消息。

试试这个:

 PostService postService = ServiceGenerator.createService(PostService.class);
 final Call<Post> call = postService.addPost(post);

Response<Post> newPostResponse = call.execute();

// Here call newPostResponse.code() to get response code
int statusCode = newPostResponse.code();
if(statusCode == 200)
    Post newPost = newPostResponse.body();
else if(statusCode == 401)
    // Do some thing... 

对每个响应都进行 401 检查并不是一个很好的方法。相反,可以在基础级别应用此检查,即通过拦截器为 Retrofit 创建对象时。看看:

public synchronized static Retrofit getClientWithRetry(final Context ctx) {
    if (clientWithRetry == null) {
        Interceptor responseCodeInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                Response response = chain.proceed(request);
                if (response.code() == 401) {
                    Log.d(LOG_TAG, "Intercepted Req: " + response.toString());
                    Response r = retryWithFreshToken(request, chain);
                    return r;
                }
                return response;
            }
        };

        int cacheSize = 10 * 1024 * 1024; // 10 MB
        Cache cache = new Cache(ctx.getCacheDir(), cacheSize);

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(logging)
                .addInterceptor(responseCodeInterceptor)
                .cache(cache)
                .build();

        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(API_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client);
        clientWithRetry = builder.build();
    }
    return clientWithRetry;
}

如果在内部观察到 401,则可以发出新的链式请求并获取令牌。 Post原来的请求可以完成。取自这个 Retrofit retry tutorial.