针对 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.
我正在使用 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.