Retrofit2+Rxjava網(wǎng)絡(luò)請求異常的統(tǒng)一封裝處理

Retrofit2+Rxjava作為主流的網(wǎng)絡(luò)請求框架,本文主要講解針對網(wǎng)絡(luò)請求的錯(cuò)誤信息進(jìn)行一次封裝,方便我們根據(jù)返回的狀態(tài)合理地在UI界面進(jìn)行顯示,同時(shí)如何主動(dòng)取消網(wǎng)絡(luò)請求的訂閱。

網(wǎng)絡(luò)請求中有很多常見的錯(cuò)誤,我們可以通過Toast彈出消息通知用戶具體的異常以及加載對應(yīng)的UI界面。除此之外,通過具體的異常信息,方便我們及時(shí)的排查項(xiàng)目中的BUG。那么我們就需要知道具體的錯(cuò)誤是什么。Retrofit2回調(diào)方法有四種,分別是:onSubscribe(),onNext()、onError()和onComplete(),他們的意思分別是:訂閱、下一步、失敗和完成。通常我們在onNext()和onError()方法中處理成功和失敗的操作。onNext()中獲取到數(shù)據(jù)的返回進(jìn)行展示,那么在onError()中只給我們一個(gè)Throwable,那么我們該如何處理呢?

一下是一個(gè)簡單的網(wǎng)絡(luò)請求,先看代碼:

   userNetWork.toGetLunBoTuEntity(new Observer<LunBoTuEntity>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(LunBoTuEntity lunBoTuEntity) {
            if (lunBoTuEntity.isSuccess()) {
                Toast.makeText(MainActivity.this, "網(wǎng)絡(luò)請求成功", Toast.LENGTH_SHORT).show();
            } else {

            }
        }

        @Override
        public void onError(Throwable e) {
            //對網(wǎng)絡(luò)請求錯(cuò)誤統(tǒng)一封裝處理
            String errorMessage = ErrorHandler.errorMessage(e);
            Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onComplete() {

        }
    });

在這里可以注意到以下一行代碼,這個(gè)就是本文的重點(diǎn),對網(wǎng)絡(luò)請求返回的錯(cuò)誤做統(tǒng)一處理:

//對網(wǎng)絡(luò)請求錯(cuò)誤統(tǒng)一封裝處理
String errorMessage = ErrorHandler.errorMessage(e);

要對返回錯(cuò)誤作統(tǒng)一處理,那么就要封裝返回?cái)?shù)據(jù)及異常類型判斷,這就要從服務(wù)器返回的數(shù)據(jù)格式說起了。我們一般請求的返回都是像下面這樣

{
   "Success": false
   "code":"200",
   "message":"Successd!",
   "data":{
         "name":"小明"
          "age":3
          "date":"2017-05-12"
   }
}

服務(wù)器端返回?cái)?shù)據(jù)約定俗稱就是大概以上的格式??赡芫唧w的code碼表示的含義不一樣,這個(gè)可以與服務(wù)器端人員交流,靈活變化,對于上述的服務(wù)器返回?cái)?shù)據(jù)我們要對errorCode做出一些判斷,可以根據(jù)自己的業(yè)務(wù)需要做出不同的操作:

public static String errorMessage(Throwable e) {
        TradeSimpleResult errBody = ErrorHandler.handle(e);
        if (errBody != null) {
            final Activity activity = AppManager.topActivity();
            String errorCode = errBody.getErrorInfo().getErrorCode();
            if (activity != null && !activity.isDestroyed()) {
                if ("401".equals(errorCode)) {
                    //token失效了
                } else if ("402".equals(errorCode)) {

                } else if ("403".equals(errorCode)) {

                } else if ("404".equals(errorCode)) {

                }else if ("500".equals(errorCode)){

                }
            }
            return errBody.getErrorInfo().getErrorMessage();
        }
        return "";
    }

對服務(wù)器返回?cái)?shù)據(jù)我們要對code做出一些判斷,code不為200(假設(shè)200表示請求網(wǎng)絡(luò)成功)就拋出異常。所以我們新建一個(gè)TradeSimpleResult類,對應(yīng)上面的數(shù)據(jù)結(jié)構(gòu)。

下面這個(gè)實(shí)體類這算是所有實(shí)體的一個(gè)基類,data可以為任何數(shù)據(jù)類型。然后要對返回結(jié)果進(jìn)行預(yù)處理,新建一個(gè)ExceptionHandle。預(yù)處理無非就是根據(jù)返回?cái)?shù)據(jù)用Gson進(jìn)行解析,Success若為true則正常處理,否則拋出異常讓ExceptionHandle進(jìn)一步處理,判斷異常為何種異常。

以下為TradeSimpleResult實(shí)體類的基類:

public class TradeSimpleResult implements Serializable{

  private boolean Success;
  private int StatusCode;
  private String Message;
  private ErrorInfoBean ErrorInfo;

  public boolean isSuccess() {
    return Success;
  }

  public void setSuccess(boolean Success) {
    this.Success = Success;
  }

  public int getStatusCode() {
    return StatusCode;
  }

  public void setStatusCode(int StatusCode) {
    this.StatusCode = StatusCode;
  }

  public String getMessage() {
    return Message;
  }

  public void setMessage(String Message) {
    this.Message = Message;
  }

  public ErrorInfoBean getErrorInfo() {
    return ErrorInfo;
  }

  public void setErrorInfo(ErrorInfoBean ErrorInfo) {
    this.ErrorInfo = ErrorInfo;
  }

  public static class ErrorInfoBean {

    private String ErrorMessage;
    private String ErrorCode;

    public String getErrorMessage() {
      return ErrorMessage;
    }

    public void setErrorMessage(String ErrorMessage) {
      this.ErrorMessage = ErrorMessage;
    }

    public String getErrorCode() {
      return ErrorCode;
    }

    public void setErrorCode(String ErrorCode) {
      this.ErrorCode = ErrorCode;
    }
  }
}

那么實(shí)體類的基類我們也封裝好了,就來看看具體封裝的ErrorHandler的代碼操作:

public class ErrorHandler {
    private static String data = "{\"Success\": false,\"StatusCode\": 500,\"Message\": \"處理失敗\", \"ErrorInfo\": {\"ErrorMessage\": \"網(wǎng)絡(luò)請求錯(cuò)誤\",\"ErrorCode\": \"404\" },\"Result\": null}";

    public static TradeSimpleResult handle(Throwable throwable) {
        if (throwable instanceof HttpException) {
            HttpException error = (HttpException) throwable;
            try {
                String string = error.response().errorBody().string();
                if (isJSONValid(string)) {
                    return new Gson().fromJson(string, TradeSimpleResult.class);
                } else {
                    return new Gson().fromJson(data, TradeSimpleResult.class);
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        } else {
            throwable.printStackTrace();
            return null;
        }
    }

    public static String errorMessage(Throwable e) {
        TradeSimpleResult errBody = ErrorHandler.handle(e);
        if (errBody != null) {
            final Activity activity = AppManager.topActivity();
            String errorCode = errBody.getErrorInfo().getErrorCode();
            if (activity != null && !activity.isDestroyed()) {
                if ("401".equals(errorCode)) {
                    //token失效了

                } else if ("402".equals(errorCode)) {

                } else if ("403".equals(errorCode)) {

                } else if ("404".equals(errorCode)) {

                }else if ("500".equals(errorCode)){

                }
            }
            return errBody.getErrorInfo().getErrorMessage();
        }
        return "";
    }

    public final static boolean isJSONValid(String jsonInString) {
        try {
            return true;
        } catch (Exception e) {
            return false;
        }
    }
 }

需要注意的是以上操作需要用到Gson對數(shù)據(jù)進(jìn)行json格式的解析,那么到現(xiàn)在為止,網(wǎng)絡(luò)請求的錯(cuò)誤返回的封裝處理就做完了,使用的話,直接在onError(Throwable e)的方法中String errorMessage = ErrorHandler.errorMessage(e);就可以拿到具體的錯(cuò)誤信息了。
源碼下載地址https://download.csdn.net/download/weitao_666/11116700

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容