我有令牌用它来发出请求,这个令牌有一些生命周期。 因此,当我收到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之前的请求后,都会调用带有无效(旧的)数据。 那么如何用新的令牌数据重复请求呢?
答案 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))
}