服务器之家

服务器之家 > 正文

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

时间:2021-07-30 11:34     来源/作者:耀东wang

通常情况下我们在与服务器进行通信的时候,不一定就不会出错,有时会出现其他的错误,这个时候我们只要和服务器约定好各种异常,在返回结果处进行判断,到底是执行错误,还是返回正常数据。具体的思路大致就是这样。这里我们定义exceptionhandle,这里我参考网上的东西,然后稍微做了一些改动。

exceptionhandle

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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进行一定的变换。

先看代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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并开始发送事件。

使用起来其实就很简单了:

?
1
2
3
4
5
6
7
8
9
10
11
12
@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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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();
      }
    });

好了对网络请求的异常处理整个思路大致就是这样了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.jianshu.com/p/860945e0de5b

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部