我向具有改造2.0的服务器发送登录请求,并且服务器返回到客户端会话令牌,但我必须在其他请求中使用该令牌,但是此令牌的生存期有限,并且当它到期时,服务器将返回HTTP错误401。
遇到此错误后,我尝试通过以下代码进行重新登录:
holder.getApi(GuideProfileApi.class) .getProfile(String.valueOf(holder.getServerId()), holder.getServerToken()) .subscribeOn(Schedulers.io()) .retryWhen(new Function, ObservableSource>>() { @Override public ObservableSource> apply(Observable throwableObservable) throws Exception { return throwableObservable.flatMap(new Function >() { @Override public ObservableSource> apply(Throwable throwable) throws Exception { if (throwable instanceof HttpException && ((HttpException)throwable).code() == 401) { RegistryLoginResult loginResult = holder.login().blockingSingle(); return holder.getApi(GuideProfileApi.class) .getProfile(String.valueOf(loginResult.getUserId()), loginResult.getSessionToken()); } return Observable.error(throwable); } }); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer () { @Override public void accept(ProfileResult profileResult) throws Exception { Log.d("Result", profileResult.toString()); } }, new Consumer () { @Override public void accept(Throwable throwable) throws Exception { Log.e("Result", throwable.getLocalizedMessage()); } });
并且发送了重试请求,但是请求的参数与不正确的请求中的参数相同(重新登录之前)。如何在再次发送请求之前更改请求的参数?
您可以使用retryWhen
,但是问题是您的retryWhen重试了您在惰性时间内创建的同一可观察对象。您的解决方案是使用运算符defer
获取host(),因为延迟它不是在您定义可观察对象时创建可观察对象,而是在被订阅者使用时创建它。
Observable.defer(()-> holder.getApi(GuideProfileApi.class) .getProfile(String.valueOf(holder.getServerId()),holder.getServerToken())) .subscribeOn(Schedulers.io()) .retryWhen(new Function, ObservableSource>>() { @Override public ObservableSource> apply(Observable throwableObservable) throws Exception { return throwableObservable.flatMap(new Function >() { @Override public ObservableSource> apply(Throwable throwable) throws Exception { if (throwable instanceof HttpException && ((HttpException)throwable).code() == 401) { RegistryLoginResult loginResult = holder.login().blockingSingle(); return holder.getApi(GuideProfileApi.class) .getProfile(String.valueOf(loginResult.getUserId()), loginResult.getSessionToken()); } return Observable.error(throwable); } }); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer () { @Override public void accept(ProfileResult profileResult) throws Exception { Log.d("Result", profileResult.toString()); } }, new Consumer () { @Override public void accept(Throwable throwable) throws Exception { Log.e("Result", throwable.getLocalizedMessage()); } });
您可以在此处查看重试的一些示例https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/errors/ObservableExceptions.java