Retrofit2+Rxjava网络请求异常的统一封装处理

Retrofit2+Rxjava作为主流的网络请求框架,本文主要讲解针对网络请求的错误信息进行一次封装,方便我们根据返回的状态合理地在UI界面进行显示,同时如何主动取消网络请求的订阅。

网络请求中有很多常见的错误,我们可以通过Toast弹出消息通知用户具体的异常以及加载对应的UI界面。除此之外,通过具体的异常信息,方便我们及时的排查项目中的BUG。那么我们就需要知道具体的错误是什么。Retrofit2回调方法有四种,分别是:onSubscribe(),onNext()、onError()和onComplete(),他们的意思分别是:订阅、下一步、失败和完成。通常我们在onNext()和onError()方法中处理成功和失败的操作。onNext()中获取到数据的返回进行展示,那么在onError()中只给我们一个Throwable,那么我们该如何处理呢?

一下是一个简单的网络请求,先看代码:

private void initData() {
        userNetWork.toGetLunBoTuEntity(new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                //如果想手动取消这个网络请求
                //d.dispose();
            }

            @Override
            public void onNext(LunBoTuEntity lunBoTuEntity) {
                if (lunBoTuEntity.isSuccess()) {
                    Toast.makeText(MainActivity.this, "网络请求成功", Toast.LENGTH_SHORT).show();
                } else {

                }
            }

            @Override
            public void onError(Throwable e) {
                //对网络请求错误统一封装处理
                String errorMessage = ErrorHandler.errorMessage(e);
                Toast.makeText(MainActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onComplete() {

            }
        });
    }

在这里可以注意到以下一行代码,这个就是本文的重点,对网络请求返回的错误做统一处理:

//对网络请求错误统一封装处理
String errorMessage = ErrorHandler.errorMessage(e);

要对返回错误作统一处理,那么就要封装返回数据及异常类型判断,这就要从服务器返回的数据格式说起了。我们一般请求的返回都是像下面这样

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

服务器端返回数据约定俗称就是大概以上的格式。可能具体的code码表示的含义不一样,这个可以与服务器端人员交流,灵活变化,对于上述的服务器返回数据我们要对errorCode做出一些判断,可以根据自己的业务需要做出不同的操作:

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 "";
    }

对服务器返回数据我们要对code做出一些判断,code不为200(假设200表示请求网络成功)就抛出异常。所以我们新建一个TradeSimpleResult类,对应上面的数据结构。

下面这个实体类这算是所有实体的一个基类,data可以为任何数据类型。然后要对返回结果进行预处理,新建一个ExceptionHandle。预处理无非就是根据返回数据用Gson进行解析,Success若为true则正常处理,否则抛出异常让ExceptionHandle进一步处理,判断异常为何种异常。

以下为TradeSimpleResult实体类的基类:

public class TradeSimpleResult implements Serializable{

  /**
   * Success : false
   * StatusCode : 500
   * Message : 处理失败
   * ErrorInfo : {"ErrorMessage":"请输入真实的身份证姓名信息","ErrorCode":"-1"}
   */

  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 {
    /**
     * ErrorMessage : 请输入真实的身份证姓名信息
     * ErrorCode : -1
     */

    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;
    }
  }
}

那么实体类的基类我们也封装好了,就来看看具体封装的ErrorHandler的代码操作:

public class ErrorHandler {
    private static String data = "{\"Success\": false,\"StatusCode\": 500,\"Message\": \"处理失败\", \"ErrorInfo\": {\"ErrorMessage\": \"网络请求错误\",\"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对数据进行json格式的解析,那么到现在为止,网络请求的错误返回的封装处理就做完了,使用的话,直接在onError(Throwable  e)的方法中String errorMessage = ErrorHandler.errorMessage(e);就可以拿到具体的错误信息了。

源码下载地址:https://download.csdn.net/download/weitao_666/11116700

你可能感兴趣的:(Android,Retrofit2,异常处理,Retrofit2,网络请求异常处理,Rxjava)