2017-04-19 4 views
0

私はトークンを要求していますが、このトークンにはlifeTimeがあります。 これで401エラーが発生したときに、別のリクエストでrefreshTokenを行う必要があります。 私はそれをスムーズに(中断なしに)したいと思っています:401を得ると、リフレッシュよりも、そして新しい利用可能なトークンで最初のリクエストを繰り返す後。新しいポスト値で補完要求を繰り返す方法

は、ここに私のコードです:と呼ばれる成功refreshToken前回の要求の後

@POST("/refresh_token") 
Observable<Auth> refreshToken(@Body BodyAuth body); 

@POST("/someLink") 
Observable<Answer> someRequest(@Body OtherBody body); 

Observable<Answer> makeSomeRequest(){ 
    retutn someRequest(new Body(currentToken)). 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .compose(StatusCodeVerifier()) 
       .retryWhen(RetryWithNewToken(requestManager)) 
} 

public class StatusCodeVerifier<T> implements Observable.Transformer<Response<T>,T> { 
    @Override 
    public Observable<T> call(Observable<Response<T>> responseObservable) { 
     return responseObservable. 
       flatMap(new Func1<Response<T>, Observable<?>>() { 
        @Override 
        public Observable<?> call(Response<T> tResponse) { 
         if (tResponse.code() == 401){ 
          throw new UnAuthorizedException("custom exception"); 
         } else { 
          return Observable.just(tResponse); 
         } 
        } 
       }); 
    } 
} 

public class RetryWithNewToken implements Func1<Observable<Throwable>, Observable<?>> { 

    private UserDataManager requestManger; 

    public RetryWithNewToken(RequestManager requestManger){ 
     this.requestManger = requestManger; 
    } 
    @Override 
    public Observable<?> call(final Observable<Throwable> attempts) { 
     return attempts.flatMap(new Func1<Throwable, Observable<?>>() { 
      @Override 
      public Observable<?> call(final Throwable throwableObservable) { 
       if (throwableObservable instanceof UnAuthorizedException){ 
        return requestManger. refreshToken().subscribe(new Action1<CbAuth>() { 
         @Override 
         public void call(TokenData newToken) { 
          updateToken(newToken); 
          //here i try to repeat previous request that was failed because of 401 error 
          Observable.just(attempts); 
         } 
        }); 
       } 
       return Observable.error(throwableObservable); 
      } 
     }); 
    } 
} 

たびに、それは、無効な(古い)データと呼ばれています。 新しいトークンデータでリクエストを繰り返すにはどうしたらいいですか?

答えて

0

someRequestObservableの引数は1回だけ初期化されているためです。また、エラーが発生した場合は、再登録するだけです。しかし、各サブスクリプションでcurrentTokenをポーリングする必要があります。 Observable.fromCallable演算子を使用して実行できます。

Observable<Answer> makeSomeRequest(){ 
    return Observable.fromCallable(() -> currentToken) // called on each subscription 
       .flatMap(token -> someRequest(new Body(token))) 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .compose(StatusCodeVerifier()) 
       .retryWhen(RetryWithNewToken(requestManager)) 
} 
関連する問題