Get response status code using Retrofit 2.0 and RxJava

I'm trying to upgrade to Retrofit 2.0 and add RxJava in my android project. I'm making an api call and want to retrieve the error code in case of an error response from the server.

Observable<MyResponseObject> apiCall(@Body body);

And in the RxJava call:

myRetrofitObject.apiCall(body).subscribe(new Subscriber<MyResponseObject>() {
@Override
public void onCompleted() {


}


@Override
public void onError(Throwable e) {


}


@Override
public void onNext(MyResponseObject myResponseObject) {
//On response from server
}
});

In Retrofit 1.9, the RetrofitError still existed and we could get the status by doing:

error.getResponse().getStatus()

How do you do this with Retrofit 2.0 using RxJava?

61995 次浏览

不像您那样声明 API 调用:

Observable<MyResponseObject> apiCall(@Body body);

你也可以这样声明:

Observable<Response<MyResponseObject>> apiCall(@Body body);

然后,您将拥有如下的订阅服务器:

new Subscriber<Response<StartupResponse>>() {
@Override
public void onCompleted() {}


@Override
public void onError(Throwable e) {
Timber.e(e, "onError: %", e.toString());


// network errors, e. g. UnknownHostException, will end up here
}


@Override
public void onNext(Response<StartupResponse> startupResponseResponse) {
Timber.d("onNext: %s", startupResponseResponse.code());


// HTTP errors, e. g. 404, will end up here!
}
}

因此,带有错误代码的服务器响应也将被传递到 onNext,您可以通过调用 reponse.code()来获得代码。

Http://square.github.io/retrofit/2.x/retrofit/retrofit/response.html

编辑: 好吧,我终于找到了电子营养在他们的评论中所说的,即只有2xx 的代码将到 onNext。事实证明我们都是对的:

If the call is declared like this:

Observable<Response<MyResponseObject>> apiCall(@Body body);

or even this

Observable<Response<ResponseBody>> apiCall(@Body body);

所有 响应都将以 onNext结束,而不管它们的错误代码如何。这是可能的,因为所有内容都通过便携式包装包装在 Response对象中。

If, on the other hand, the call is declared like this:

Observable<MyResponseObject> apiCall(@Body body);

或者这个

Observable<ResponseBody> apiCall(@Body body);

事实上,只有2xx 的反应将到 onNext。其他的都将被包装在一个 HttpException和发送到 onError。这也是有意义的,因为没有 Response包装,什么 应该被发射到 onNext?假设请求不成功,发出的唯一明智的东西将是 null..。

在 onError 方法内部,将此放置以获取代码

((HttpException) e).code()

你应该注意到,从 翻新2开始,所有代码为 2xx的响应都将从 onNext ()回调调用,而其余的 HTTP 代码将像4xx 一样,在 OnError ()回调调用5xx,使用 Kotlin我在 OnError ()中得到了类似的结果:

mViewReference?.get()?.onMediaFetchFinished(downloadArg)
if (it is HttpException) {
val errorCode = it.code()
mViewReference?.get()?.onMediaFetchFailed(downloadArg,when(errorCode){
HttpURLConnection.HTTP_NOT_FOUND -> R.string.check_is_private
else -> ErrorHandler.parseError(it)
})
} else {
mViewReference?.get()?.onMediaFetchFailed(downloadArg, ErrorHandler.parseError(it))
}