如何使用新帖子值

时间:2017-04-19 13:03:14

标签: android rx-java retrofit2

我有令牌用它来​​发出请求,这个令牌有一些生命周期。 因此,当我收到401错误时,我需要刷新其他请求。 我想为用户顺利完成(没有任何中断):如果获得401,则进行刷新,然后使用新的可用令牌重复第一次请求。

这是我的代码:

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

每次成功调用refreshToken之前的请求后,都会调用带有无效(旧的)数据。 那么如何用新的令牌数据重复请求呢?

1 个答案:

答案 0 :(得分:0)

这是因为您只使用其参数初始化someRequest Observable一次。当发生错误时,您只需重新订阅它。但是您必须在每个订阅上轮询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))
}