评论

收藏

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

编程语言 编程语言 发布于:2021-08-17 12:19 | 阅读数:228 | 评论:0

通常情况下我们在与服务器进行通信的时候,不一定就不会出错,有时会出现其他的错误,这个时候我们只要和服务器约定好各种异常,在返回结果处进行判断,到底是执行错误,还是返回正常数据。具体的思路大致就是这样。这里我们定义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 static  class 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

关注下面的标签,发现更多相似文章