使用Retrofit 2.0和RxJava获取响应状态代码

时间:2015-11-18 08:23:48

标签: android retrofit rx-java android-networking rx-android

我正在尝试升级到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?

3 个答案:

答案 0 :(得分:169)

而不是像你那样声明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 ...

答案 1 :(得分:91)

在onError中放入此方法获取代码

((HttpException) e).code()

答案 2 :(得分:7)

您应该注意,从 Retrofit2 开始,代码 2xx 的所有响应都将从onNext()回调调用,其余 HTTP代码比如4xx,将在 onError()回调中调用5xx,使用 Kotlin 我在 onError()<中提出了类似的内容/ strong>:

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))
  }