2015-11-28 17 views
16

मैं आरएक्सजेवा और रेट्रोफिट के लिए काफी नया हूं और इसके साथ अपनी एपीआई कॉल लिखने की कोशिश कर रहा हूं। सभी API कॉल, त्रुटि जो के रूप में सामान्य प्रारूप में है पर एक JSON शरीर लौटरेट्रोफिट 2.0 + आरएक्सजेवा + त्रुटि जेएसओएन बॉडी

{"errors":[{"code":100, "message":"Login/Password not valid", "arguments":null}]} 

वर्तमान में लॉगिन API कॉल (दूसरों को भी इसी तरह के हैं) है के लिए मेरे कोड,

mConnect.login(id, password) 
     .subscribe(new Subscriber<Token>() { 
      @Override 
      public void onCompleted() { 
       Log.d(TAG, "onCompleted()"); 
      } 

      @Override 
      public void onError(Throwable e) { 
       Log.e(TAG, "onError(): " + e); 
       if (e instanceof HttpException) { 
        // dump e.response().errorBody() 
       } 
      } 

      @Override 
      public void onNext(Token token) { 
       Log.d(TAG, "onNext(): " + token); 
      } 
     }); 

जब मैं ऑनरर() पर एक त्रुटि प्राप्त करें, मैं इसके बजाय त्रुटि शरीर में JSON को POJO पर स्वचालित रूप से डीकोड करना चाहता हूं और इसका उपयोग कर सकता हूं। क्या यह अन्य सभी एपीआई कॉल के लिए अधिमानतः एक स्थान पर ऐसा करने का कोई तरीका है। किसी भी मदद की सराहना की है।

उत्तर

5

मैं आपके तर्क को समाहित करने के लिए onErrorResumeNext ऑपरेटर के साथ एक पुन: प्रयोज्य Transformer के उपयोग का सुझाव दूंगा। कोड में टिप्पणी करने के लिए

<T> Observable.Transformer<T, T> parseHttpErrors() { 
    return new Observable.Transformer<T, T>() { 
     @Override 
     public Observable<T> call(Observable<T> observable) { 
      return observable.onErrorResumeNext(new Func1<Throwable, Observable<? extends T>>() { 
       @Override 
       public Observable<? extends T> call(Throwable throwable) { 
        if (throwable instanceof HttpException) { 
         HttpErrorPojo errorPojo = // deserialize throwable.response().errorBody(); 

         // Here you have two options, one is report this pojo back as error (onError() will be called), 
         return Observable.error(errorPojo); // in this case HttpErrorPojo would need to inherit from Throwable 

         // or report this pojo back as part of onNext() 
         return Observable.just(errorPojo); //in this case HttpErrorPojo would need to inherit from <T> 
        } 
        // if not the kind we're interested in, then just report the same error to onError() 
        return Observable.error(throwable); 
       } 
      }); 
     } 
    }; 
} 

वेतन ध्यान, जब से तुम निर्णय करने के लिए है आप पार्स प्रतिक्रिया onError() या onNext() रिपोर्ट करना चाहते हैं कि क्या: यह कुछ इस तरह दिखाई चाहते हैं।

तो फिर तुम इस ट्रांसफार्मर कहीं भी अपने API कॉल में इस तरह का उपयोग कर सकते हैं:

mConnect.login(id, password) 
     .compose(this.<Token>parseHttpErrors()) // <-- HERE 
     .subscribe(new Subscriber<Token>() { 
      @Override 
      public void onCompleted() { 
       Log.d(TAG, "onCompleted()"); 
      } 

      @Override 
      public void onError(Throwable e) { 
       Log.e(TAG, "onError(): " + e); 
       if (e instanceof HttpErrorPojo) { 
        // this will be called if errorPojo was reported via Observable.error() 
       } 
      } 

      @Override 
      public void onNext(Token token) { 
       Log.d(TAG, "onNext(): " + token); 
       if (token instanceof HttpErrorPojo) { 
        // this will be called if errorPojo was reported via Observable.just() 
       } 
      } 
     }); 
0

deserialize एक मुद्दा भी हो सकता है। आप retrofit converter to deserialize it (या इसे स्वयं कर सकते हैं) का उपयोग कर सकते हैं।

मेरे समाधान murki से एक के लिए एक सा कहते हैं:,

<T> Observable.Transformer<T, T> parseHttpErrors() { 
     return new Observable.Transformer<T, T>() { 
      @Override 
      public Observable<T> call(Observable<T> observable) { 
       return observable.onErrorResumeNext(new Func1<Throwable, Observable<? extends T>>() { 
        @Override 
        public Observable<? extends T> call(Throwable throwable) { 
         if (throwable instanceof HttpException) { 
          Retrofit retrofit = new Retrofit.Builder() 
            .baseUrl(SERVER_URL) // write your url here 
            .addConverterFactory(GsonConverterFactory.create()) 
            .build(); 
          Converter<ResponseBody, Error> errorConverter = 
            retrofit.responseBodyConverter(Error.class, new Annotation[0]); 
          // Convert the error body into our Error type. 
          try { 
           Error error = errorConverter.convert(((HttpException) throwable).response().errorBody()); 
           // Here you have two options, one is report this pojo back as error (onError() will be called), 
           return Observable.error(new Throwable(error.getMessage())); 
          } 
          catch (Exception e2) { 
           return Observable.error(new Throwable()); 
          } 

         } 
         // if not the kind we're interested in, then just report the same error to onError() 
         return Observable.error(throwable); 
        } 
       }); 
      } 
     }; 
    } 

और फिर onError() पर

@Override 
public void onError(Throwable e) { 
    progressBar.setVisibility(View.GONE); // optional 
    if (!TextUtils.isEmpty(e.getMessage())) { 
      // show error as you like 
      return; 
    } 
    // show a default error if you wish 
} 
संबंधित मुद्दे