登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

android retrofit+rxjava如何处理响应码为非200的情况? [复制链接]

2018-1-8 16:55
陪你唠嗑 阅读:188 评论:2 赞:1
Tag:  

一、前言

我想绝大多数小伙伴现在都在用Okhttp或者retrofit来做网络请求了吧,毕竟squar出品必属精品。不废话,今天就是来聊聊http请求响应码的问题。大家都知道,android网络请求是通过httpurlconnection来实现的(httpclient已经在最新的Google源码中废弃),在发起网络请求以后,会有一个Response对象来给我们返回响应信息,而且只有在response code为200的时候才是响应成功,400是请求的url中包含非法字符次,404是请求的url不存在,500是服务器内部出错。

下面给个大致的归类

状态码响应类别说明
1XX信息性状态码服务器正在处理请求
2XX成功状态码请求已正常处理完毕
3XX重定向状态码需要进行额外操作以完成请求
4XX客户端错误状态码客户端原因导致服务器无法处理请求
5XX服务器错误状态码服务器原因导致响应请求出错

android http code响应码 状态码

二、一般的retrofit+rxjava的请求方式如下

mModel.getOneDayTempData(timestamp)
                .subscribe(new Observer<TemperatureBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        
                    }

                    @Override
                    public void onNext(TemperatureBean temperatureBean) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

如果响应成功,也就是response code为200的时候,会执行onNext,如果响应码非200的情况下会执行onError(),而且在onNext()的时候可以获取到响应信息,这是大家都知道的。但是响应失败的时候,onError(Throwable e) 这个方法的参数是Throwable对象,我们通过e.toString()来打印一下结果

我故意发送了一个错误的请求,结果只是打印了头部信息,并没有我们想要的response

retrofit2.adapter.rxjava2.HttpException: HTTP 500 Internal Server Error

在这里我就困扰了好久,按照httpurlconnection,就算是500也能拿到这个response的,我想会不会是这个Throwable信息不全,然后我想既然retrofit是通过okhttp来实现请求的,我就用okhttp试试

OkHttpUtils.doPostRequest(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                
            }

            @Override
            public void onResponse(Call call, Response response) {
                String body = response.body().string();
                Log.i(TAG, "onResponse: "+body);
            }
        });

果然在这个response里面拿到了code为500的时候的body信息

所以现在只要我能把onError(Throwable e)这个Throwable转换成Response不就行了吗?这时候查看了一下源码,Exception是继承于Throwable的,所以来看看这个HttpException的源码
HttpException部分源码

public class HttpException extends Exception {
  private static String getMessage(Response<?> response) {
    if (response == null) throw new NullPointerException("response == null");
    return "HTTP " + response.code() + " " + response.message();
  }

  private final int code;
  private final String message;
  private final transient Response<?> response;

  public HttpException(Response<?> response) {
    super(getMessage(response));
    this.code = response.code();
    this.message = response.message();
    this.response = response;
  }
}

果然这里有我想要的code和Response对象,这下就好办了,我只需要把Throwable向下转型转成HttpException就可以获取信息了

向下转型的方式如下

 if (throwable instanceof HttpException){
          ResponseBody body = ((HttpException) throwable).response().errorBody();
          try {
                 Log.i(TAG, "onFailure: "+body.string());
             } catch (IOException e) {
                  e.printStackTrace();
             }
        }

我公司的后台有部分errorCode和errorMsg是放在为500的这个异常信息里面的,我必须要去处理这个onError(Throwable e),拿到这里面的信息去提示用户,这样才能保证程序的健壮性。好了,希望能帮到有同样需要的小伙伴吧!

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(2)
0号凯迪 2018-1-9 10:56
给力,学习了
回复
你好,再见 2018-1-9 17:52
给力,学习了
回复

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

广告投放| 申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

返回顶部