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