最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何利用Retrofit+RxJava實現(xiàn)網(wǎng)絡(luò)請求的異常處理

 更新時間:2019年04月09日 15:13:54   作者:耀東wang  
這篇文章主要介紹了如何利用Retrofit+RxJava實現(xiàn)網(wǎng)絡(luò)請求的異常處理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

通常情況下我們在與服務器進行通信的時候,不一定就不會出錯,有時會出現(xiàn)其他的錯誤,這個時候我們只要和服務器約定好各種異常,在返回結(jié)果處進行判斷,到底是執(zhí)行錯誤,還是返回正常數(shù)據(jù)。具體的思路大致就是這樣。這里我們定義ExceptionHandle,這里我參考網(wǎng)上的東西,然后稍微做了一些改動。

ExceptionHandle

public class ExceptionHandle {

  private static final int UNAUTHORIZED = 401;
  private static final int FORBIDDEN = 403;
  private static final int NOT_FOUND = 404;
  private static final int REQUEST_TIMEOUT = 408;
  private static final int INTERNAL_SERVER_ERROR = 500;
  private static final int BAD_GATEWAY = 502;
  private static final int SERVICE_UNAVAILABLE = 503;
  private static final int GATEWAY_TIMEOUT = 504;

  public static ResponseException handleException(Throwable e){
    //轉(zhuǎn)換成ResponseException,根據(jù)狀態(tài)碼判定錯誤信息
    ResponseException ex;
    if(e instanceof HttpException){
      HttpException httpException=(HttpException)e;
      /**
       * 傳入狀態(tài)碼,根據(jù)狀態(tài)碼判定錯誤信息
       */
      ex=new ResponseException(e,ERROR.HTTP_ERROR);
      switch (httpException.code()){
        case UNAUTHORIZED:
          ex.message="未驗證";
          break;
        case FORBIDDEN:
          ex.message="服務禁止訪問";
          break;
        case NOT_FOUND:
          ex.message="服務不存在";
          break;
        case REQUEST_TIMEOUT:
          ex.message="請求超時";
          break;
        case GATEWAY_TIMEOUT:
          ex.message="網(wǎng)關(guān)超時";
          break;
        case INTERNAL_SERVER_ERROR:
          ex.message="服務器內(nèi)部錯誤";
          break;
        case BAD_GATEWAY:

          break;
        case SERVICE_UNAVAILABLE:
          break;
        default:
          ex.message = "網(wǎng)絡(luò)錯誤";
          break;
      }
      return ex;
    }else if(e instanceof JsonParseException
        || e instanceof JSONException
        || e instanceof ParseException){
      ex=new ResponseException(e,ERROR.PARSE_ERROR);
      ex.message="解析錯誤";
      return ex;
    }else if(e instanceof ConnectException){
      ex=new ResponseException(e,ERROR.NETWORD_ERROR);
      ex.message="連接失敗";
      return ex;
    }else if(e instanceof javax.net.ssl.SSLHandshakeException){
      ex=new ResponseException(e,ERROR.SSL_ERROR);
      ex.message="證書驗證失敗";
      return ex;
    }else {
      ex=new ResponseException(e,ERROR.UNKNOWN);
      ex.message="未知錯誤";
      return ex;
    }
  }
  /**
   * 約定異常
   */
 public static  class ERROR{
    /**
     * 自定義異常
     */
    private static final int UNAUTHORIZED = 401;//請求用戶進行身份驗證
    private static final int UNREQUEST=403;//服務器理解請求客戶端的請求,但是拒絕執(zhí)行此請求
    private static final int UNFINDSOURCE=404;//服務器無法根據(jù)客戶端的請求找到資源
    private static final int SEVERERROR=500;//服務器內(nèi)部錯誤,無法完成請求。
    /**
     * 協(xié)議出錯
     */
    public static final int HTTP_ERROR = 1003;
    /**
     * 未知錯誤
     */
    public static final int UNKNOWN = 1000;
    /**
     * 解析錯誤
     */
    public static final int PARSE_ERROR = 1001;
    /**
     * 網(wǎng)絡(luò)錯誤
     */
    public static final int NETWORD_ERROR = 1002;
    /**
     * 證書出錯
     */
    public static final int SSL_ERROR = 1005;
  }
  /**
   * 自定義Throwable
   */
  public static class ResponseThrowable extends Exception{
    public int code;
    public String message;
    public ResponseThrowable(Throwable throwable,int code){
      super(throwable);
      this.code=code;
    }
  }
  /**
   * 服務器異常
   */
  public class ServerException extends RuntimeException{
    public int code;
    public String message;
  }

  /**
   * 統(tǒng)一異常類,便于處理
   */
  public static class ResponseException extends Exception{
    public int code;
    public String message;
    public ResponseException (Throwable throwable,int code){
      super(throwable);
      this.code=code;
    }
  }
}

然后自己定義了一個Observer

public abstract class BaseObserver<T> implements Observer<T> {
  private Context context;

  public BaseObserver(Context context){
    this.context=context;
  }

  @Override
  public void onSubscribe(Disposable d) {

  }
  @Override
  public void onNext(T t) {

  }
  @Override
  public void onError(Throwable e) {
    if(e instanceof ExceptionHandle.ResponseException){
      onError((ExceptionHandle.ResponseException)e);
    }else{
      onError(new ExceptionHandle.ResponseException(e,ExceptionHandle.ERROR.UNKNOWN));
    }
  }
  @Override
  public void onComplete() {

  }
  public abstract void onError(ExceptionHandle.ResponseException exception);
}

這里發(fā)生錯誤時,Observerble會先調(diào)用onError(Throwable e),按照我的寫法呢,會繼續(xù)調(diào)用自定義onError。

那么什么時候我們對服務器的返回結(jié)果進行判斷,什么時候該發(fā)出異常了,請繼續(xù)往下看:

這里我們打算用到ObservableTransformer,Transformer其實就是就是對Observable進行一定的變換。

先看代碼:

  public static class HandleFuc<T> implements Function<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>, T> {
    @Override
    public T apply(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response) {
      if (!Response.getCode().equals("200")){
        Throwable e=new Throwable("約定錯誤");
        /**
         * 可以根據(jù)不同的狀態(tài)嘛返回不同的提示信息
         * 與服務器約定返回異常信息
         */
        ExceptionHandle.ResponseException responseException = new ExceptionHandle.ResponseException(e, ExceptionHandle.ERROR.HTTP_ERROR);
        return (T) Observable.error(responseException);//發(fā)出錯誤異常
      }
      return (T) Observable.just(Response);//發(fā)出服務器數(shù)據(jù),返回Observable<Response>
    }
  }

  //處理錯誤的變換
  public static class ErrorTransformer<T> implements ObservableTransformer {
    @Override
    public Observable<T> apply(Observable upstream) {
      return (Observable<T>) upstream.flatMap(new HandleFuc<T>());//flatMap會重新創(chuàng)建一個Observable,當它處理完事件后會匯入原先的Observable對象。
    }
  }

說明:我們的HandleFuc其實就是對服務器返回來的結(jié)果進行判斷,邏輯很簡單了,錯誤就拋出異常直接執(zhí)行error方法。如果沒有錯誤,就發(fā)送正常數(shù)據(jù)。這里值的說明一點的是,flatMap會重新創(chuàng)建一個Observable,當它處理完事件后會重新匯入初始的Observerble并開始發(fā)送事件。

使用起來其實就很簡單了:

@Provides
  ErrorTransformer provideErrorTransformer(){
    return new ErrorTransformer();
  }

 public Observable<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>> getApplication(PageParmForm pageParmForm){
    return retrofit.create(Service.class)
        .getApplicationList(pageParmForm)
        .compose(errorTransformer)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());
  }

直接用compose方法包裹起來即可。

最后看看Activity:

new NetRepository().getApplication(new PageParmForm(Constant.orderStr,Constant.pageNum,Constant.pageSize))
    .subscribe(new BaseObserver<UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>>>(NetWorkActivity.this) {
      @Override
      public void onError(ExceptionHandle.ResponseException exception) {
        myToast.showToast(NetWorkActivity.this,exception.getMessage());
        Log.d("carhandbook",exception.getMessage());
      }

      @Override
      public void onNext(UserGuideSoftConfigRForm<UserGuideSoftConfigPageInfo<List<UserguideSoftConfig>>> Response) {
        data=Response.getData().getList();
        code=Response.getCode();
        myToast.showToast(NetWorkActivity.this,code);
        generateAdapter.setData(data);
        generateAdapter.notifyDataSetChanged();
      }
    });

好了對網(wǎng)絡(luò)請求的異常處理整個思路大致就是這樣了。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java集合框架線程同步代碼詳解

    java集合框架線程同步代碼詳解

    這篇文章主要介紹了java集合框架線程同步代碼詳解,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • java8新特性-Stream入門學習心得

    java8新特性-Stream入門學習心得

    這篇文章主要介紹了java8新特性-Stream入門學習心得,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 32位和64位皆適用的MyEclipse安裝教程

    32位和64位皆適用的MyEclipse安裝教程

    這篇文章主要為大家詳細介紹了32位和64位皆適用的MyEclipse安裝教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java并發(fā)編程中構(gòu)建自定義同步工具

    Java并發(fā)編程中構(gòu)建自定義同步工具

    這篇文章主要介紹了Java并發(fā)編程中構(gòu)建自定義同步工具,本文講解了可阻塞狀態(tài)依賴操作的結(jié)構(gòu)、有界緩存實現(xiàn)基類示例、阻塞實現(xiàn)方式一:拋異常給調(diào)用者、阻塞實現(xiàn)方式二:通過輪詢和休眠、阻塞實現(xiàn)方式三:條件隊列等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • 淺談spring注解之@profile

    淺談spring注解之@profile

    這篇文章主要介紹了淺談spring注解之@profile,@profile通過配置來改變參數(shù),這里整理的詳細的用法,有興趣的可以了解一下
    2017-10-10
  • Java 基于雪花算法生成分布式id

    Java 基于雪花算法生成分布式id

    SnowFlake 算法(雪花算法), 是Twitter開源的分布式id生成算法。其核心思想就是: 使用一個64 bit的long型的數(shù)字作為全局唯一id。本文講述Java 基于雪花算法生成分布式id的方法
    2021-06-06
  • SpringMVC Mybatis配置多個數(shù)據(jù)源并切換代碼詳解

    SpringMVC Mybatis配置多個數(shù)據(jù)源并切換代碼詳解

    這篇文章主要介紹了SpringMVC Mybatis配置多個數(shù)據(jù)源并切換代碼詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Java線程中synchronized和volatile關(guān)鍵字的區(qū)別詳解

    Java線程中synchronized和volatile關(guān)鍵字的區(qū)別詳解

    這篇文章主要介紹了Java線程中synchronized和volatile關(guān)鍵字的區(qū)別詳解,synchronzied既能夠保障可見性,又能保證原子性,而volatile只能保證可見性,無法保證原子性,volatile不需要加鎖,比synchronized更輕量級,不會阻塞線程,需要的朋友可以參考下
    2024-01-01
  • 使用Spring注入Hibernate驗證框架

    使用Spring注入Hibernate驗證框架

    這篇文章主要介紹了使用Spring注入Hibernate驗證框架方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java語言如何生成plist下載ipa文件

    java語言如何生成plist下載ipa文件

    這篇文章主要介紹了java語言如何生成plist下載ipa文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論

启东市| 广汉市| 塔河县| 东山县| 扎囊县| 电白县| 奇台县| 增城市| 宜君县| 柘城县| 隆德县| 岱山县| 青冈县| 江山市| 建平县| 都江堰市| 岑溪市| 张家界市| 恩平市| 连江县| 元氏县| 建水县| 治多县| 松滋市| 巴里| 师宗县| 綦江县| 太仓市| 德江县| 偏关县| 丽水市| 英山县| 临泽县| 龙岩市| 吴川市| 昂仁县| 盘山县| 惠东县| 乃东县| 四子王旗| 友谊县|