Java合并接口返回数据_RxJava结合Retrofit对网络请求结果的统一处理

不同的网络请求有不同的返回结果,当同时也有很多相同的地方,比如数据的整体结构可以是这样:

{

"status": 1000,

"msg": "调用权限失败",

"data": {

***

***

}

}

如果接口数据的设计如上,那么每个请求都会有如下三点相同的部分

状态码

网络异常

相同的网络请求策略

既然有相同的部分,那么就有必要对相同的部分统一处理

主要功能图解

整体采用MVP设计模式如下

c88ebf1e0ca7

MVP架构

其中ModelPresenter为所有网络请求的Presenter,如下

c88ebf1e0ca7

ModelPresenter

DataSevice为Retrofit请求接口如下

c88ebf1e0ca7

DataService

网络层的整体流程如下

c88ebf1e0ca7

网络层流程

其中第三层返回的是HttpBean,第二层返回的是业务层需要的T类型

具体实现

模型设计

在和后台对接的时候,定义一个统一的数据结构,这样才好统一处理状态码,利用泛型,我们可以设计接口返回的数据模型为

public class HttpBean {

private String msg;

private T data;

private int status;

}

不同的网络请求只需要传入相应的数据模型即可,那么利用retrofit请求数据的接口如下

public interface DataService {

@GET(RequestCons.MY_BOX)

Observable> getBox(@Query("client_id") String client_id, @Query("client_secret") String secret, @Query("visit_user_id") long user_id);

@GET(RequestCons.COMMENTS_LIST)

Observable> getComments(@Query("client_id") String client_id, @Query("client_secret") String secret, @Query("object_id") long object_id);

@GET(RequestCons.TOPIC)

Observable> getTopic(@Query("client_id") String client_id, @Query("client_secret") String secret, @Query("id") long id);

}

业务层向模型层请求数据的接口如下

public interface ModelPresenter {

/** * 下载box数据接口 */

Observable loadBoxData(String client_id, String secret, long user_id);

/** * 下载评论数据接口 */

Observable loadCommentData(String client_id, String secret, long object_id);

/** * 下载Topic商品 */

Observable loadTopic(String client_id, String secret, long id);

}

通过对比两个接口,可以发现业务层无需关心状态码了,只会拿到Observable而不是Obervable>

ModelPresenterImpl的实现

ModelPresenterImpl继承自BaseModelImpl,本身的实现其实很简单,主要工作就是调用DataService对应的方法,然后过滤状态码,代码如下

public class ModelPresenterImpl extends BaseModelImpl implements ModelPresenter {

@Override

public Observable loadBoxData(String client_id, String secret, long user_id) {

return filterStatus(mDataService.getBox(client_id,secret,user_id));

}

@Override

public Observable loadCommentData(String client_id, String secret, long object_id) {

return filterStatus(mDataService.getComments(client_id,secret,object_id));

}

@Override

public Observable loadTopic(String client_id, String secret, long id) {

return filterStatus(mDataService.getTopic(client_id,secret,id));

}

}

BaseModelImpl的实现

BaseModelImpl做了以下两点工作

创建OkHttpClient、Retrofit、DataService

public BaseModelImpl() {

this.baseUrl = RequestCons.BASE_URL;

OkHttpClient client = new OkHttpClient.Builder()

.connectTimeout(10, TimeUnit.SECONDS)

.build();

mRetrofit = new Retrofit.Builder()

.baseUrl(baseUrl)

.client(client)

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.build();

mDataService = mRetrofit.create(DataService.class);

}

利用Rxjava的map操作符过滤状态码

/** * 给返回结果去掉状态码等属性,

* 如果是查询出错,则返回状态码对应的描述给用户

* @param observable

* @return

*/

public Observable filterStatus(Observable observable){

return observable.map(new ResultFilter());

}

private class ResultFilter implements Func1, T> {

@Override

public T call(HttpBean tHttpBean) {

if (tHttpBean.getStatus() != 1){

throw new ApiException(tHttpBean.getStatus());

}

return tHttpBean.getData();

}

}

此处代码是一个关键点,利用操作符map给请求的数据"去壳",只返回给业务层所需要的模型,如果当前请求的状态码不是成功的标志,那么抛出异常,交给应用层的OnError处理,确保应用层的onNext方法只处理成功的结果,纯粹专一。

配置状态码过滤器

状态码过滤器一共需要2个类

常量说明类

public class ResponseCons {

public static final int STATUS_SUCCESS = 1;

public static final String SUCCESS_MSG = "成功";

public static final int STATU_1000 = 1000;

public static final String FAILURE_1000 = "调用权限失败";

}

状态码匹配工具类

public class StatusUtils {

public static class StatusResult{

public int status;

public String desc;

public boolean isSuccess;

}

private static StatusResult mStatusResult = new StatusResult();

public static StatusResult judgeStatus(int status) {

String desc = "";

boolean isSuccess = false;

switch (status) {

case ResponseCons.STATUS_SUCCESS:

desc = ResponseCons.SUCCESS_MSG;

isSuccess = true;

break;

case ResponseCons.STATU_1000:

desc = ResponseCons.FAILURE_1000;

break;

}

mStatusResult.status = status;

mStatusResult.desc = desc;

mStatusResult.isSuccess = isSuccess;

return mStatusResult;

}

}

在BaseModelImpl中对网络请求结果的状态码进行判断,如果不是标志成功的状态码,那么就抛出一个异常,在异常中利用状态码匹配工具类找到对应错误描述并且返回

public class ApiException extends RuntimeException {

public ApiException(int status) {

super(getErrorDesc(status));

}

private static String getErrorDesc(int status){

return StatusUtils.judgeStatus(status).desc;

}

}

随着业务的扩展,如出现新的状态码,那么只需要往常量类和匹配工具类增加状态码和错误描述即可,不需要更改网络层其它代码,还可以拓展成将错误码和对应描述信息存储在本地,当成配置文件,那么当产品发布之后,如果后台增加错误码,只需要download新的状态码配置文件即可,不需要发布新版本应用。

其它网络错误处理

以上已经实现了网络层的功能,包括发起请求,解析返回结果并且统一过滤状态码,将请求成功的结果返回到Observable.onNext(),将失败结果返回到observable.onError()。

然而网络请求并不是一直稳定的,所以所有网络请求都有可能出现超时、无网络链接或者其它40X,50X错误。

因此还需要再做一层错误过滤,在Retrofit中,所有的异常都会抛出,并且最终由Observable的onError接收,所以我们可以自定义一个FilterSubscriber继承自Subscriber,实现onError接口,对传入的throwable参数进行判处理,代码如下

public abstract class FilterSubscriber extends Subscriber {

public String error;

@Override

public abstract void onCompleted();

@Override

public void onError(Throwable e) {

if (e instanceof TimeoutException || e instanceof SocketTimeoutException

|| e instanceof ConnectException){

error = "超时了";

}else if (e instanceof JsonSyntaxException){

error = "Json格式出错了";

//假如导致这个异常触发的原因是服务器的问题,那么应该让服务器知道,所以可以在这里

//选择上传原始异常描述信息给服务器

}else {

error = e.getMessage();

}

}

}

由于我们提取出异常处理类,在异常处理类的onError( )中统一对所有异常进行处理,所以当一些异常确定是或者疑似是服务器的bug,抑或是未知bug,我们应该及时上报服务器,让服务器收集错误信息,及时修复,所以在onError( )中选择上传数据请求的异常信息是一个不错的选择。当然服务器的异常也可以后台自己收集,这里只是提供一种策略而已。

应用层调用

做完了发送请求,解析数据,错误处理,最后就是应用层调用了,代码如下:

@Overridepublic void loadTopicSuccess() {

Observable observable = mModelPresenter.loadTopic("bt_app_ios", "9c1e6634ce1c5098e056628cd66a17a5", 1346);

observable.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new FilterSubscriber() {

@Override

public void onCompleted() {

MLog.d("Topic信息下载完毕");

}

@Override

public void onNext(TopicData data) {

mMainView.showSuccess(data);

}

@Override

public void onError(Throwable e) {

super.onError(e);

mMainView.showError(error);

}

});

}

需要注意的是,在onError(Throwable e){ }中第一行代码需要super.onError(e),然后接下去的异常信息的描述是error字符串。

做完以上工作之后,往后如果需要添加新的接口,那么只需要以下几步

在requestCons添加新的接口的文件路径

增加相应的bean文件

在DataService中添加新的接口方法

在ModelPresenter添加新的接口方法并且在Impl中实现

而不需要再处理以下内容

客户端的创建

状态码过滤

网络异常过滤

上传的源码使用MVP设计模式的思想,如果想了解如何使用MVP的同学可以下载看看。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OkHttp、RxJavaRetrofit是个非常常用的组合,用来进行网络请求处理。 首先,OkHttp是一个开源的HTTP客户端,提供了简洁的接口,用于与服务器进行通信,并且支持HTTP/2协议,拥有连接池、请求重试和缓存等功能。 然后,RxJava是一个基于观察者模式的异步编程库,可以用于处理异步操作,如网络请求、文件IO等。它的核心是Observable(被观察者)和Subscriber(订阅者),通过各种操作符可以对数据进行变换和处理。 最后,Retrofit是一个RESTful风格的HTTP请求库,它基于OkHttp,使用了Retrofit的注解和接口定义的方式,可以方便地进行网络请求。它支持动态代理,可以将网络请求接口转化为对应的HTTP请求,支持同步和异步请求,并且可以将响应数据转化为Java对象。 综上所述,我们可以使用OkHttp作为底层网络库,然后结合RxJavaRetrofit进行网络请求数据处理。使用Retrofit的注解和接口定义方式,可以简化网络请求的代码,并且通过RxJava的操作符可以对请求结果进行变换和处理,使得代码更加清晰和可读性。 在使用过程中,可以先创建一个Retrofit实例,并指定OkHttpClient作为网络客户端,然后定义一个接口,在该接口中使用Retrofit的注解,定义网络请求的方法。最后,通过创建该接口的实例,即可进行网络请求,并结合RxJava进行操作。 总之,使用OkHttp、RxJavaRetrofit组合进行网络请求可以提高效率和可读性,并且可以处理各种复杂的网络场景,是一种非常实用的方式。 ### 回答2: OKHTTP、RXJavaRetrofit是Android开发中常用的三个库,可以一起使用来进行网络请求数据处理。 OKHTTP是一个用于处理网络请求的库,可以发送HTTP请求并获取服务器返回数据。它提供了简洁的API和高效的网络堆栈,可以很好地处理网络请求。我们可以使用OKHTTP来发送SOAP请求到WebService,并获得响应。 RXJava是一个流编程库,它提供了一种被观察者和观察者模式,可以简化异步操作和事件处理。我们可以使用RXJava处理OKHTTP返回的响应数据,在主线程或后台线程中进行处理,实现数据的异步处理和流式编程。 Retrofit是一个基于OKHTTP的RESTful风格的网络请求库,它提供了一种简洁的方式来定义和发送HTTP请求,并将响应转换为可用的Java对象。我们可以使用Retrofit来定义WebService接口,然后使用注解来指定请求方法、路径和参数,Retrofit会自动帮我们处理请求和响应。 通过OKHTTP的原生支持、RXJava的异步处理Retrofit网络请求,我们可以很方便地使用OKHTTP、RXJavaRetrofit一起发送WebService请求。首先,我们可以使用Retrofit定义WebService接口,再使用RXJava处理OKHTTP返回的响应数据,实现简洁高效的网络请求数据处理。 综上所述,OKHTTP、RXJavaRetrofit是Android开发中常用的网络请求库,它们能够很好地协作,实现对WebService的请求和响应的处理。通过使用它们,我们可以简化网络请求的编写,并实现高效的数据处理。 ### 回答3: OkHttp、RxJavaRetrofit是三个在Android开发中常用的网络请求库,它们在一起能够提供更加便捷和高效的网络请求处理。 首先,OkHttp是一个开源的HTTP客户端,它能够处理网络请求、连接管理、请求重试等一系列的网络相关事务。它的特点是简单易用、性能优越、可定制性强。我们可以通过使用OkHttp来发送和接收基于HTTP的请求响应,并进行网络请求的管理和处理。 其次,RxJava是一个响应式编程框架,它基于观察者模式和函数式编程的思想,提供了一系列强大的操作符和线程切换的能力。我们可以使用RxJava处理异步任务,加快网络请求的响应时间,并且提供方便的线程切换和错误处理机制。 最后,Retrofit是一个RESTful风格的网络请求框架,它结合了OkHttp和RxJava的强大功能。它提供了一种简单的方式来定义和处理RESTful API的请求和响应。我们可以使用Retrofit来创建和处理webservice的请求,根据API的接口定义来发送请求,并将返回的结果映射到Java对象中。 综上所述,使用OkHttp、RxJavaRetrofit能够方便地进行webservice的网络请求,并在处理过程中提供更好的性能和便利性。这三个库的结合能够大大简化网络请求的开发工作,提高开发效率,并提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值