使用 Retrofit 2.0 和 RxJava 获取响应状态码
Get response status code using Retrofit 2.0 and RxJava
我正在尝试升级到 Retrofit 2.0 并在我的 android 项目中添加 RxJava。我正在调用 api 并希望在服务器响应错误时检索错误代码。
Observable<MyResponseObject> apiCall(@Body body);
并且在 RxJava 调用中:
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
}
});
在 Retrofit 1.9 中,RetrofitError 仍然存在,我们可以通过以下方式获取状态:
error.getResponse().getStatus()
你如何使用 RxJava 在 Retrofit 2.0 中做到这一点?
而不是像您那样声明 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
编辑: 好吧,我终于开始研究 e-nouri 在他们的评论中所说的内容,即只有 2xx 代码会转到 onNext
。事实证明我们都是对的:
如果调用是这样声明的:
Observable<Response<MyResponseObject>> apiCall(@Body body);
甚至这个
Observable<Response<ResponseBody>> apiCall(@Body body);
所有 响应将在 onNext
中结束,无论它们的错误代码如何。这是可能的,因为一切都被 Retrofit 包装在一个 Response
对象中。
另一方面,如果调用是这样声明的:
Observable<MyResponseObject> apiCall(@Body body);
或这个
Observable<ResponseBody> apiCall(@Body body);
实际上只有 2xx 响应会转到 onNext
。其他所有内容都将包装在 HttpException
中并发送到 onError
。这也是有道理的,因为没有 Response
包装器,什么 应该 发送到 onNext
?鉴于请求不成功,唯一明智的做法是 null
...
在 onError 方法中放入此代码以获取代码
((HttpException) e).code()
您应该注意,从 Retrofit2 开始,所有代码为 2xx 的响应都将从 onNext() 回调中调用,其余 HTTP 代码 像 4xx,5xx 将在 onError() 回调中调用,使用 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))
}
我正在尝试升级到 Retrofit 2.0 并在我的 android 项目中添加 RxJava。我正在调用 api 并希望在服务器响应错误时检索错误代码。
Observable<MyResponseObject> apiCall(@Body body);
并且在 RxJava 调用中:
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
}
});
在 Retrofit 1.9 中,RetrofitError 仍然存在,我们可以通过以下方式获取状态:
error.getResponse().getStatus()
你如何使用 RxJava 在 Retrofit 2.0 中做到这一点?
而不是像您那样声明 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
编辑: 好吧,我终于开始研究 e-nouri 在他们的评论中所说的内容,即只有 2xx 代码会转到 onNext
。事实证明我们都是对的:
如果调用是这样声明的:
Observable<Response<MyResponseObject>> apiCall(@Body body);
甚至这个
Observable<Response<ResponseBody>> apiCall(@Body body);
所有 响应将在 onNext
中结束,无论它们的错误代码如何。这是可能的,因为一切都被 Retrofit 包装在一个 Response
对象中。
另一方面,如果调用是这样声明的:
Observable<MyResponseObject> apiCall(@Body body);
或这个
Observable<ResponseBody> apiCall(@Body body);
实际上只有 2xx 响应会转到 onNext
。其他所有内容都将包装在 HttpException
中并发送到 onError
。这也是有道理的,因为没有 Response
包装器,什么 应该 发送到 onNext
?鉴于请求不成功,唯一明智的做法是 null
...
在 onError 方法中放入此代码以获取代码
((HttpException) e).code()
您应该注意,从 Retrofit2 开始,所有代码为 2xx 的响应都将从 onNext() 回调中调用,其余 HTTP 代码 像 4xx,5xx 将在 onError() 回调中调用,使用 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))
}