Retrofit 2.0 및 RxJava를 사용하여 응답 상태 코드 가져 오기


107

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으로 어떻게 수행합니까?

답변:


185

다음과 같이 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오류 코드에 관계없이로 끝납니다 . 모든 것이 ResponseRetrofit에 의해 개체에 싸여 있기 때문에 가능합니다 .

반면에 호출이 다음과 같이 선언되면 :

Observable<MyResponseObject> apiCall(@Body body);

아니면 이거

Observable<ResponseBody> apiCall(@Body body);

실제로 2xx 응답 만 onNext. 다른 모든 것은로 포장되어로 HttpException전송됩니다 onError. Response래퍼가 없으면 무엇 방출해야 onNext하나요? 요청이 성공적이지 않았다는 점을 감안할 때 방출 할 수있는 유일한 것은 null...


16
HTTP 코드 4xx를 찾는 사람들의 경우 onError에서 HttpException으로 끝납니다. onNext에는 2xx 만 있습니다.
e-nouri

2
흥미 군요 ... 방금 다시 확인했는데 ( gist.github.com/DavidMihola/17a6ea373b9312fb723b ) 시도한 모든 코드에 onNext404 등이 포함 되었습니다 . Retrofit v2.0.0-beta3를 사용했습니다.
david.mihola

@ e-nouri : 방금 귀하의 의견을 고려하여 내 답변에 단락을 추가했습니다!
david.mihola

1
@ david.mihola add를 통해 Retrofit을 빌드 하면 원래 응답을 얻는 방법 GsonConverterFactory과 마찬가지로 Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())?
Honghe.Wu

1
오류 처리 외에도 본문과 함께 제공되는 응답 헤더를 검사 할 수 있기를 원할 수 있습니다 Response. 이는 . 나도 거의 사용하지 않지만 존재한다는 것을 아는 것이 좋다고 생각합니다.
david.mihola 2017

112

onError 메소드 내부에 코드를 가져 오기 위해 이것을 넣으십시오.

((HttpException) e).code()

7
이것은 내가 지금까지 본 것 중 가장 과소 평가 된 답변 중 하나 일 수 있습니다. 이것은 천재입니다. 를 사용하여 응답에 필요한 모든 작업을 수행 할 수 있습니다 HttpException. RxJava를 사용하고 있으며 HTTP 400 BAD REQUEST. 대단히 감사합니다!
GabrielOshiro

29
NetworkErrors는 IOExceptions이고 상태 코드가 없기 때문에 이전에 HttpException의 인스턴스인지 확인하십시오.
Benjamin Mesing

@BenjaminMesing에서 NetworkError에 대해 말하면서 구독하기 전에 Rx에서 더 많은 다운 스트림 연산자 (map / flatMap / forEach 등)를 수행하는 경우 가능한 예외 유형이 많을 수 있으며 반드시 오류가 아닐 수 있습니다. 네트워크 요청.
Mark Keen

java.lang.ClassCastException가 : java.lang.Throwable의이 retrofit2.HttpException 캐스트 할 수없는
어딘가의 누군가를

7

당신의 같은 점에 유의해야한다 Retrofit2 코드와 모든 응답 가 2xx이 onNext () 콜백와의 나머지 부분에서 호출되는 HTTP 코드 4XX 같은, 5XX가 호출됩니다 의 OnError () 사용하여 콜백 코 틀린 I의 한 같은 것을 함께했다 이것은 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))
  }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.