2014-11-13 3 views
0

Я действительно новичок в RxJava, но я пытаюсь реализовать API с помощью Retrofit framework и RxJava. На стороне сервера есть служба авторизации, которая обрабатывает сеанс пользователя, и в случае некоторой задержки в действиях пользователя сервер прерывает свою сессию. После этого пользователь должен снова войти в систему, чтобы выполнить новый вызов API. Плохая вещь - сервер всегда возвращает HTTP-код 200, а для уведомления об истечении срока действия использует некоторый пользовательский ответ JSON с кодом срока действия, поэтому RxJava не запускает Exception во время операции onNext, потому что RxJava считает, что запрос был успешно принят.Принудительный повторный запрос запроса после пользовательских исключений API в RxJava

Вопрос: Как реализовать правильный поток для обработки пользовательских исключений API, таких как истечение и повторный запрос с запросом после какого-либо другого запроса (в моем случае relogin)?

Что-то вроде этого:

  • приложения -> Логин()
  • сервера -> {код: 0, ...}
  • приложения -> getUsers()
  • сервера -> {код: 0, ...}
  • ------- 30 минут -------
  • приложение -> getPicture()
  • сервер -> {код: 99,. ..} // s ession истек, пользователь неавторизованный
  • приложение -> Логин()
  • сервер -> {код: 0, ...}
  • приложение -> getPicture()
  • сервер -> {код: 0,. ..}

Я думал о чем-то вроде этого, но без успеха:

 Observable.create(new Observable.OnSubscribe<BackendResponse<String>>() { 
     @Override 
     public void call(Subscriber<? super Response<String>> subscriber) { 
      try { 
       Response<String> response; 
       subscriber.onNext(response = getInterface().getUsers()); 

       if (response != null) { 
        response.checkData(); // throws ServerException in case of code != 0 
       } 
       subscriber.onCompleted(); 
      } catch (Exception e) { 
       subscriber.onError(e); 
      } 
     } 
    }).subscribeOn(Schedulers.io()).retryWhen(new RetryWithSessionRefresh(new SessionService())).subscribe(); 

и RetryWithSessionRefresh является:

public class RetryWithSessionRefresh implements 
    Func1<Observable<? extends Notification<?>>, Observable<?>> { 

private final SessionService sessionSerivce; 

public RetryWithSessionRefresh(SessionService sessionSerivce) { 
    this.sessionSerivce = sessionSerivce; 
} 

@Override 
public Observable<?> call(Observable<? extends Notification<?>> attempts) { 
    return attempts 
      .flatMap(new Func1<Notification<?>, Observable<?>>() { 
       @Override 
       public Observable<?> call(final Notification notification) { 
        final Throwable throwable = notification.getThrowable(); 
        if (throwable instanceof ServerException) { 
         final ServerException backendException = (ServerException) throwable; 
         if (backendException.getBackendErrorCode() == Response.AUTHORIZATION_FAILED) { 
          return sessionSerivce 
            .observeSessionToken() 
            .doOnNext(new Action1<TokenCallback>() { 
             @Override 
             public void call(TokenCallback token) { 
              if (token != null) { 
               DataHolder.getInstance().setAuthToken(token.getToken()); 
              } 
             } 
            }) 
            .doOnError(new Action1<Throwable>() { 
             @Override 
             public void call(Throwable throwable) { 
              DataHolder.getInstance().setAuthToken(""); 
             } 
            }); 
         } 
        } 
        return Observable.error(notification.getThrowable()); 
       } 
      }); 
} 

ответ

0

Может быть, вы ван flapMap ваш ответ, и вернуть ваш наблюдаемым в случае успеха с Observable.just (ваш пункт) или ошибка, когда ответ не является действительным с Observable.error (ваша ошибка)

Смежные вопросы