2017-09-28 18 views
0

En utilisant Retrofit2 (Ver: 2.3.0), OkHTTP3 (Ver: 3.9.0) avec RxJava2 (Ver: 2.0.0)Répéter un appel api-Retrofit2.0 en fonction de la réponse du serveur

Scénario d'un appel reste api

Observable<ServerResponse> backendService.isUserVerified("someuserName") 

qui retourne un 200 Ok HTTP

Réponse Le succès attendu JSON POJO si l'utilisateur est vérifiée

{ 

    user: "someUserName", 

    isVerified: "yes" 

} 

Réponse succès escompté JSON POJO si l'utilisateur n'a pas vérifié

{ 

    user: "someUserName", 

    isVerified: "no" 

} 

code suivant est que je suis en train de mettre en œuvre

backendService.isUserVerified("someuserName") 
.subscribeOn(Schedulers.io()) 
.observeOn(AndroidSchedulers.mainThread()) 

    //Want to add a flatmap (or some other operator) 
    .flatmap(new Function<ServerResponse>, ObservableSource<?>>(){ 
      @Override 
      public ObservableSource<?> apply(ServerResponse serverResponse) throws Exception { 
       if(0 != serverResponse.getisVerified.compareToIgnoreCase("yes")) { 
       return Observable.error(new CustomException()); 
      } 
      return //current observable. 
    } 

.retryWhen(mRetryHandler) 
.subscribeWith(observer); 

Le but est de lancer une exception personnalisée si elle est vérifiée == pas de sorte que l'opérateur retryWhen() puisse intervenir pour répéter la chaîne d'appel, sinon, il faut passer par la chaîne jusqu'à subscribe().

Des pointeurs/une aide?

+0

Pouvez-vous expliquer plus ce que vous voulez faire? Vous voulez remplacer 'ObservableResource ' avec ce que vous voulez continuer? –

+0

Oui ObservableSource pour les scénarios d'erreur et de repli ... – shyguy

Répondre

0

Vous pouvez simplement utiliser doOnNext plutôt que flatmap:

backendService.isUserVerified("someuserName") 
.subscribeOn(Schedulers.io()) 
.observeOn(AndroidSchedulers.mainThread()) 

//we can throw an exception if the user is not verified or keep the response as it is otherwise 
.doOnNext(serverResponse -> { 
         if(0 != serverResponse.getisVerified.compareToIgnoreCase("yes")) 
         { 
          throw new CustomException(); 
         } 
        }) 

.retryWhen(mRetryHandler) 
.subscribeWith(observer); 

L'opérateur doOnNext effectue simplement une fonction à l'élément émis sans le modifier. Vous voulez simplement lancer une erreur dans un cas spécifique en fonction de l'élément et ne pas le modifier pour qu'il soit approprié. Comme vous ne modifiez pas les threads avant l'opérateur doOnNext ou après, avant d'utiliser l'élément dans l'opérateur suivant, vous savez qu'il lancera l'exception AVANT de continuer au cas où il devrait le lancer.

Voici un exemple de la documentation liée de l'opérateur:

Observable.just(1, 2, 3) 
     .doOnNext(new Action1<Integer>() { 
     @Override 
     public void call(Integer item) { 
     if(item > 1) { 
      throw new RuntimeException("Item exceeds maximum value"); 
     } 
     } 
    }).subscribe(new Subscriber<Integer>() { 
    @Override 
    public void onNext(Integer item) { 
     System.out.println("Next: " + item); 
    } 
    @Override 
    public void onError(Throwable error) { 
     System.err.println("Error: " + error.getMessage()); 
    } 
    @Override 
    public void onCompleted() { 
     System.out.println("Sequence complete."); 
    } 
}); 

[output:]

Next: 1

Error: Item exceeds maximum value

0

Si vous voulez lancer une erreur en utilisant Observable.error(new CustomException());, vous n'avez pas besoin de faire fonction pour renvoyer un objet spécifique de l'erreur et un autre un pour la réponse attendue, c'est une exception et ira à la méthode onError(). Votre ObservableResource<?> doit renvoyer la réponse attendue qui est récupérée dans la méthode onResponse() à partir de Subscriber. Si vous lancez une erreur en utilisant Observable.error(), votre chaîne sera brisée et l'erreur sera envoyée au onError().

Modifier

Vous devez utiliser la fonction retry, car vous retourner ServerResponse et vous pouvez vérifier si est valide ou non. En utilisant retryWhen, vous obtenez seulement l'erreur quand quelque chose ne va pas. Dans votre cas, vous n'obtenez aucune erreur, vous obtenez la réponse. Dans ce cas, vous n'avez pas besoin de cela flatMap

.retry(new BiPredicate<ServerResponse, Throwable>() { 
      @Override 
      public boolean test(ServerResponse serverResponse, Throwable throwable) throws Exception { 
       return serverResponse.getisVerified.equals("no"); 
      } 
    }) 
+0

Je suppose que vous avez manqué l'opérateur de tentative ci-dessous dans la chaîne ...Il va consommer l'exception lancée. Ma question est exactement comment créer cette observable. – shyguy

+0

Je ne sais pas comment créer ObservableSource ... – shyguy

+0

@shyguy J'ai mis à jour ma réponse –