Daha önce ama buna benzer bir şey yaptık OAuth yetkilendirmesiyle. Temel olarak, her istek için oturum çerezi ekleyen bir RequestInterceptor ile başlatılmış bir RestAdapter var. RequestInterceptor, oturumun yetkilendirildiği her zaman yeni bir oturum çerezi alır.
aşağıdaki Güçlendirme DİNLENME arabirim tanımı
aşağıdaki örnek kod kullanılır:
interface ApiService {
@GET("/examples/v1/example")
Observable<Example> getExample();
}
ayrıntılı önleme her dinlenme isteği bir göz alır ve başlıkları, sorgu parametreleri ekleyebilir veya URL değiştirebilir. Bu örnek, çerezin HTTP başlığı olarak eklendiğini varsayar.
class CookieHeaderProvider implements RequestInterceptor {
private String sessionCookie = "";
public CookieHeaderProvider() {
}
public void setSesstionCookie(String sessionCookie) {
this.sessionCookie = sessionCookie;
}
@Override
public void intercept(RequestFacade requestFacade) {
requestFacade.addHeader("Set-Cookie", sessionCookie);
}
}
Bu, ima ettiğiniz SessionService'dir. Bu sorumluluk, oturum çerezini yetkilendiren/yenileyen ağ isteğini yapmaktır. Bu istek yeniden deneme mantığı gözlemlenebilir her Retrofit eklenebilir böylece
class SessionService {
// Modify contructor params to pass in anything needed
// to get the session cookie.
SessionService(...) {
}
public Observable<String> observeSessionCookie(...) {
// Modify to return an Observable that when subscribed to
// will make the network request to get the session cookie.
return Observable.just("Fake Session Cookie");
}
}
RestService sınıf Retrofitler arayüzü sarar.
class RestService {
private final apiService;
private final sessionSerivce;
private final cookieHeaderProvider;
RestService(ApiService apiService,
SessionService sessionSerivce,
CookieHeaderProvider cookieHeaderProvider) {
this.apiService = apiService;
this.sessionSerivce = sessionSerivce;
this.cookieHeaderProvider = cookieHeaderProvider;
}
Observable<Example> observeExamples() {
// Return a Retrofit Observable modified with
// session retry logic.
return
apiService
.observeExamples()
.retryWhen(new RetryWithSessionRefresh(sessionSerivce, cookieHeaderProvider));
}
}
yeniden deneme mantığı aşağıda oturum çerezi güncelleme ve sunucuya gönderilen oturum tanımlama bir HTTP Yetkisiz (401) hata dönerse o zaman başarısız DİNLENME isteklerini yeniden denemek için SessionService kullanacaktır.
public class RetryWithSessionRefresh implements
Func1<Observable<? extends Throwable>, Observable<?>> {
private final SessionService sessionSerivce;
private final CookieHeaderProvider cookieHeaderProvider;
public RetryWithSessionRefresh(SessionService sessionSerivce,
CookieHeaderProvider cookieHeaderProvider) {
this.sessionSerivce = sessionSerivce;
this.cookieHeaderProvider = cookieHeaderProvider;
}
@Override
public Observable<?> call(Observable<? extends Throwable> attempts) {
return attempts
.flatMap(new Func1<Throwable, Observable<?>>() {
public int retryCount = 0;
@Override
public Observable<?> call(final Throwable throwable) {
// Modify retry conditions to suit your needs. The following
// will retry 1 time if the error returned was an
// HTTP Unauthoried (401) response.
retryCount++;
if (retryCount <= 1 && throwable instanceof RetrofitError) {
final RetrofitError retrofitError = (RetrofitError) throwable;
if (!retrofitError.isNetworkError()
&& retrofitError.getResponse().getStatus() == HttpStatus.SC_UNAUTHORIZED) {
return sessionSerivce
.observeSessionCookie()
.doOnNext(new Action1<String>() {
@Override
public void call(String sessionCookie) {
// Update session cookie so that next
// retrofit request will use it.
cookieHeaderProvider.setSesstionCookie(sessionCookie);
}
})
.doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
// Clear session cookie on error.
cookieHeaderProvider.setSesstionCookie("");
}
});
}
}
// No more retries. Pass the original
// Retrofit error through.
return Observable.error(throwable);
}
});
}
}
Müşteri başlatma kodu buna benzer görünecektir:
CookieHeaderProvider cookieHeaderProvider = new CookieHeaderProvider();
SessionService sessionSerivce = new SessionService();
ApiService apiService =
new RestAdapter.Builder()
.setEndpoint(...)
.setClient(...)
.setRequestInterceptor(cookieHeaderProvider)
.build()
.create(ApiService.class);
RestService restService =
new RestService(apiService, sessionSerivce, cookieHeaderProvider);
Sonra RestService gelen gözlemlenebilir bir dinlen ve ağ isteğini başlaması abone.
Observable<Example> exampleObservable =
restService
.observeExamples();
Subsctiption subscription =
exampleObservable
.subscribe(new Observer<Example>() {
void onNext(Example example) {
// Do stuff with example
}
void onCompleted() {
// All done.
}
void onError(Throwalbe e) {
// All API errors will end up here.
}
});
Aslında oldukça düzgün görünüyor. Teşekkürler! – midnight
hatası: uyumsuz türler: RetryWithSessionRefresh Func1 Öğesine dönüştürülemiyor Süper Gözlenebilir Throwable uzanır> ,? Gözlemlenebilir >> aslında yalnızca RxJava'nın subflix – desgraci
@desgraci'den dönüştürülmesiyle çalışır. RetryWhen() API'si, RxJava 1.0'da değiştirildi. 1.0+ uyumluluk için cevabı güncelledim. – kjones