web-dev-qa-db-ja.com

4xxエラーに対するRetrofit 2同期呼び出しエラー処理

私はAndroid-priority-jobqueueを使用していて、レトロフィットを使用して残りのAPIに同期呼び出しを行っていますが、エラーを示すjsonを送り返す401 Unauthorizedエラーのようなエラーの処理方法がわかりません。非同期呼び出しを行う場合は簡単ですが、アプリをジョブマネージャーに合わせています。以下は、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);
}
11
CaptRisky

応答コードを確認し、適切なメッセージを表示してください。

これを試して:

 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... 
7
FAЯAƸ

すべての応答で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が観察された場合、新しい連鎖リクエストを作成し、トークンをフェッチできます。元のリクエストを完了できる投稿。これから取得 Retrofit retry tutorial

0
KnowIT