Arce 发表于 2021-8-17 12:19:57

如何利用Retrofit+RxJava实现网络请求的异常处理

通常情况下我们在与服务器进行通信的时候,不一定就不会出错,有时会出现其他的错误,这个时候我们只要和服务器约定好各种异常,在返回结果处进行判断,到底是执行错误,还是返回正常数据。具体的思路大致就是这样。这里我们定义exceptionhandle,这里我参考网上的东西,然后稍微做了一些改动。
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){
    //转换成responseexception,根据状态码判定错误信息
    responseexception ex;
    if(e instanceof httpexception){
      httpexception httpexception=(httpexception)e;
      /**
       * 传入状态码,根据状态码判定错误信息
       */
      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="网关超时";
          break;
      case internal_server_error:
          ex.message="服务器内部错误";
          break;
      case bad_gateway:

          break;
      case service_unavailable:
          break;
      default:
          ex.message = "网络错误";
          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 staticclass error{
    /**
   * 自定义异常
   */
    private static final int unauthorized = 401;//请求用户进行身份验证
    private static final int unrequest=403;//服务器理解请求客户端的请求,但是拒绝执行此请求
    private static final int unfindsource=404;//服务器无法根据客户端的请求找到资源
    private static final int severerror=500;//服务器内部错误,无法完成请求。
    /**
   * 协议出错
   */
    public static final int http_error = 1003;
    /**
   * 未知错误
   */
    public static final int unknown = 1000;
    /**
   * 解析错误
   */
    public static final int parse_error = 1001;
    /**
   * 网络错误
   */
    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;
}

/**
   * 统一异常类,便于处理
   */
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);
}
这里发生错误时,observerble会先调用onerror(throwable e),按照我的写法呢,会继续调用自定义onerror。
那么什么时候我们对服务器的返回结果进行判断,什么时候该发出异常了,请继续往下看:
这里我们打算用到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("约定错误");
      /**
       * 可以根据不同的状态嘛返回不同的提示信息
       * 与服务器约定返回异常信息
       */
      exceptionhandle.responseexception responseexception = new exceptionhandle.responseexception(e, exceptionhandle.error.http_error);
      return (t) observable.error(responseexception);//发出错误异常
    }
    return (t) observable.just(response);//发出服务器数据,返回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会重新创建一个observable,当它处理完事件后会汇入原先的observable对象。
}
}
说明:我们的handlefuc其实就是对服务器返回来的结果进行判断,逻辑很简单了,错误就抛出异常直接执行error方法。如果没有错误,就发送正常数据。这里值的说明一点的是,flatmap会重新创建一个observable,当它处理完事件后会重新汇入初始的observerble并开始发送事件。
使用起来其实就很简单了:


@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();
      }
    });
好了对网络请求的异常处理整个思路大致就是这样了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CodeAE代码之家。
原文链接:https://www.jianshu.com/p/860945e0de5b

文档来源:http://www.zzvips.com/article/179949.html
页: [1]
查看完整版本: 如何利用Retrofit+RxJava实现网络请求的异常处理