Retrofit 2 - 为同一请求管理 http“204 无内容”和“200”有内容
Retrofit 2 - Manage http "204 No content" and "200" with content for the same request
我正在使用 Retrofit 2 和 OkHttp 3,以及 RxJava2
我正在使用一些参数调用服务器。根据参数,服务器 return 是一个带有对象列表的 JSON。但是,如果 return 没有任何内容,而不是 return 使用空列表 JSON,服务器 return '204 - 无内容'。结果我得到一个 NullPointerException。
我知道如何管理 JSON 响应,我知道如何管理 204 响应,但我不知道如何管理同一个调用。
我可以使用拦截器,但由于我有很多调用,我的 Retrofit 客户端只创建一次,然后在必要时使用 Dagger2 注入。
我该如何处理这个案例?
我使用 onErrorResumeNext 进行错误响应。例如
mSubscription.add(mViewModel.getMyPohybyFromSqlServer("3", drupoh)
.subscribeOn(Schedulers.computation())
.observeOn(rx.android.schedulers.AndroidSchedulers.mainThread())
.doOnError(throwable -> { Log.e(TAG, "Error xxx " + throwable.getMessage());
hideProgressBar();
Toast.makeText(getActivity(), "Server not connected", Toast.LENGTH_SHORT).show();
})
.onErrorResumeNext(throwable -> empty())
.subscribe(this::setPohyby));
根据@eurosecom 的建议,我已经解决了我的问题,如下所述。唯一的问题是我希望来自服务器的 'No Content' 响应由 Retrofit 作为 'success' 进行管理,但使用此解决方案它仍然作为错误进行管理。
改装客户端
return new OkHttpClient.Builder()
.addInterceptor(new GeneralInterceptor(callback))
.build
private static class GeneralInterceptor implements Interceptor {
//...
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder requestBuilder = originalRequest.newBuilder();
Response response = chain.proceed(requestBuilder.build());
// Throw specific Exception on HTTP 204 response code
if (response.code() == 204) {
throw new NoContentException("There is no content");
}
return response; // Carry on with the response
}
}
在演示者中
mModel.performRequest()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onErrorResumeNext(throwable -> {
if (throwable instanceof NoContentException) {
return Observable.empty();
}
return Observable.error(throwable);
})
.subscribe(res -> {
//... Manage the result
}, throwable -> {
//... On error
}
);
我正在使用 Retrofit 2 和 OkHttp 3,以及 RxJava2
我正在使用一些参数调用服务器。根据参数,服务器 return 是一个带有对象列表的 JSON。但是,如果 return 没有任何内容,而不是 return 使用空列表 JSON,服务器 return '204 - 无内容'。结果我得到一个 NullPointerException。
我知道如何管理 JSON 响应,我知道如何管理 204 响应,但我不知道如何管理同一个调用。
我可以使用拦截器,但由于我有很多调用,我的 Retrofit 客户端只创建一次,然后在必要时使用 Dagger2 注入。
我该如何处理这个案例?
我使用 onErrorResumeNext 进行错误响应。例如
mSubscription.add(mViewModel.getMyPohybyFromSqlServer("3", drupoh)
.subscribeOn(Schedulers.computation())
.observeOn(rx.android.schedulers.AndroidSchedulers.mainThread())
.doOnError(throwable -> { Log.e(TAG, "Error xxx " + throwable.getMessage());
hideProgressBar();
Toast.makeText(getActivity(), "Server not connected", Toast.LENGTH_SHORT).show();
})
.onErrorResumeNext(throwable -> empty())
.subscribe(this::setPohyby));
根据@eurosecom 的建议,我已经解决了我的问题,如下所述。唯一的问题是我希望来自服务器的 'No Content' 响应由 Retrofit 作为 'success' 进行管理,但使用此解决方案它仍然作为错误进行管理。
改装客户端
return new OkHttpClient.Builder()
.addInterceptor(new GeneralInterceptor(callback))
.build
private static class GeneralInterceptor implements Interceptor {
//...
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder requestBuilder = originalRequest.newBuilder();
Response response = chain.proceed(requestBuilder.build());
// Throw specific Exception on HTTP 204 response code
if (response.code() == 204) {
throw new NoContentException("There is no content");
}
return response; // Carry on with the response
}
}
在演示者中
mModel.performRequest()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onErrorResumeNext(throwable -> {
if (throwable instanceof NoContentException) {
return Observable.empty();
}
return Observable.error(throwable);
})
.subscribe(res -> {
//... Manage the result
}, throwable -> {
//... On error
}
);