我有以下课程:
public class SessionStore {
Subject<Session, Session> subject;
public SessionStore() {
subject = new SerializedSubject<>(BehaviorSubject.create(new Session());
}
public void set(Session session) {
subject.onNext(session);
}
public Observable<UserSession> observe() {
return subject.distinctUntilChanged();
}
}
在活动中,我观察会话并对每次更改执行网络操作:
private Subscription init() {
return sessionStore
.observe()
.flatMap(new Func1<Session, Observable<Object>>() {
@Override
public Observable<Object> call(Session session) {
return (session.isValid()
? retrofitService.getThingForValid()
: retrofitService.getThingForInalid())
.subscribeOn(Schedulers.io());
}
})
.subscribe(...);
}
现在我有一个Okhttp请求拦截器,当网络响应为非200代码时,我将会话实例从有效设置为无效。
这就是:
getThingForValid()
已执行,但失败。 getThingForInvalid()
方法。 重要的是要知道这个执行发生在上一次Retrofit调用的中间。这是因为OkHttp客户端被Retrofit包装,所有拦截器都在Retrofit返回之前执行。
考虑到这一点,你意识到第二个电话正在由Retrofit执行和处理,而第一个电话尚未完成。
我试图在流中忽略此异常,但第二次调用仍被Retrofit取消。
你有什么想法让我的概念有用吗?
答案 0 :(得分:0)
如果您在令牌过期时收到响应代码401
:
您需要将Authenticator
添加到OkHttpClient.Builder
builder.authenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
final LoginResponse newLoginResponse = refreshTokenClient.refreshToken();
//save new token locally, if needed
return response
.request()
.newBuilder()
.removeHeader("Api-Auth-Token") // removing old header
.addHeader("Api-Auth-Token", newLoginResponse.getAuthToken())
.build();
}
});
,其中
public interface RefreshTokenService {
@PUT("/api/v1/tokens")
LoginResponse refreshToken();
}
但请注意:每次响应代码为Authenticator
时,此401
都会运行。