Rtrofit+Rxjava网络请求封装

好几年前封装的框架一直没上传,趁现在升级写下。

     简介Retrofit是android的网络请求库,是一个RESTful的HTTP网络请求框架的封装(基于okhttp)。它内部网络请求的工作,本质上是通过OkHttp完成,而Retrofit仅负责网络请求接口的封装。

目录

一、引包

二、网络请求分为三个包分别为data、httptool、request三个pakage包。

三、pakage包分析

       3.1.data

              3.1.1HttpBaseResponse

   3.1.2.HttpDisposable

        3.1.3.HttpResponseInterface

3.2.httptool 为http工具类的封装

    3.2.1 添加cookie拦截

  3.2.2.HttpException自定义异常抛出

  3.2.3 HttpInterceptor请求拦截器

3.2.4.ResponseConverterFactory处理服务器返回数据将数据转换成对象

 3.2.5 UploadUtils 文件上传

3.3 request

3.3.1.ApiAddress网络请求接口地址

3.3.2.HttpFactory网络请求

3.3.3HttpRequest

3.3.4ServerAddress

四、使用

4.1.在应用的applacation中初始化

4.2.请求示例


一、引包

    //    retrofit2implementation 'com.squareup.retrofit2:retrofit:2.4.0'implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'implementation 'com.squareup.retrofit2:converter-gson:2.4.0'//    RxJavaimplementation 'io.reactivex.rxjava2:rxandroid:2.0.2'implementation 'io.reactivex.rxjava2:rxjava:2.1.12'

二、网络请求分为三个包分别为data、httptool、request三个pakage包。

      data:数据处理封装类

      httptool:网络请求工具

      request:请求处理

三、pakage包分析

       3.1.data

              data中有三个对象,分别对应  HttpBaseResponse(http响应处理)、HttpDisposable(与rxjava请求回调处理)、HttpResponseInterface(获取处理掉code和msg后的信息)。

              3.1.1HttpBaseResponse

/*** @author shizhiyin*/
public interface HttpResponseInterface {/*** 获取处理掉code和msg后的信息** @param gson* @param response* @return*/String getResponseData(Gson gson, String response);}

   3.1.2.HttpDisposable


/*** @author shizhiyin* 返回数据*/
public abstract class HttpDisposable<T> extends DisposableObserver<T> {public HttpDisposable() {}@Overrideprotected void onStart() {}@Overridepublic void onNext(T value) {success(value);}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}public abstract void success(T t);
}

        3.1.3.HttpResponseInterface

/*** @author shizhiyin*/
public interface HttpResponseInterface {/*** 获取处理掉code和msg后的信息** @param gson* @param response* @return*/String getResponseData(Gson gson, String response);}

3.2.httptool 为http工具类的封装

    3.2.1 添加cookie拦截


public class AddCookiesInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {if (!NetworkUtils.isConnected()) {throw new HttpException("网络连接异常,请检查网络后重试");}Request.Builder builder = chain.request().newBuilder();HashSet<String> preferences = Hawk.get(Constants.HawkCode.COOKIE);if (preferences != null) {for (String cookie : preferences) {builder.addHeader("Cookie", cookie);Log.v("OkHttp", "Adding Header: " + cookie);// This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp}}return chain.proceed(builder.build());}
}

  3.2.2.HttpException自定义异常抛出

    


/*** 自定义异常抛出** @author shizhiyin*/
public class HttpException extends RuntimeException {public HttpException(String message) {this.message = message;}public HttpException(int code, String message) {this.message = message;this.code = code;}@Overridepublic String getMessage() {return TextUtils.isEmpty(message) ? "" : message;}public int getCode() {return code;}private int code;private String message;}

  3.2.3 HttpInterceptor请求拦截器


/*** 自定义* 请求拦截器** @author shizhiyin*/public class HttpInterceptor implements Interceptor {private static final Charset UTF8 = Charset.forName("UTF-8");private static String REQUEST_TAG = "请求";/*** 通过拦截器* 添加请求头* 及* 打印请求结果*/@Overridepublic Response intercept(Chain chain) throws IOException {if (!NetworkUtils.isConnected()) {throw new HttpException("网络连接异常,请检查网络后重试");}Request request = chain.request();request = getHeaderRequest(request);//打印请求logRequest(request);Response response = chain.proceed(request);//
//        if (!response.headers("Set-Cookie").isEmpty()) {
//            HashSet<String> cookies = new HashSet<>();
//            for (String header : response.headers("Set-Cookie")) {
//                cookies.add(header);
//            }
//            Hawk.put(Constants.HawkCode.COOKIE, cookies);
//        }////打印响应logResponse(response);return response;}/*** 添加header*/public Request getHeaderRequest(Request request) {//        LoginRequestBean loginData =null;LoginRequestBean loginData = Hawk.get(Constants.HawkCode.LOGIN_TOKEN_INFO);Request headRequest;if (loginData != null) {
//            Logger.d("===缓存获取token=="+loginData.getToken());headRequest = request.newBuilder().addHeader("Content-Type", "application/json").addHeader("terminal", "doctor").addHeader("Authorization", loginData.getToken()).build();} else {headRequest = request.newBuilder().addHeader("Content-Type", "application/json").addHeader("terminal", "doctor").build();}return headRequest;}/*** 打印请求信息** @param request*/private void logRequest(Request request) {Log.d(REQUEST_TAG + "method", request.method());Log.d(REQUEST_TAG + "url", request.url().toString());Log.d(REQUEST_TAG + "header", request.headers().toString());if (request.method().equals("GET")) {return;}try {RequestBody requestBody = request.body();String parameter = null;Buffer buffer = new Buffer();requestBody.writeTo(buffer);parameter = buffer.readString(UTF8);buffer.flush();buffer.close();Log.d(REQUEST_TAG + "参数", parameter);} catch (IOException e) {e.printStackTrace();}}/*** 打印返回结果** @param response*/private void logResponse(Response response) {try {ResponseBody responseBody = response.body();String rBody = null;BufferedSource source = responseBody.source();source.request(Long.MAX_VALUE);Buffer buffer = source.buffer();Charset charset = UTF8;MediaType contentType = responseBody.contentType();if (contentType != null) {try {charset = contentType.charset(UTF8);} catch (UnsupportedCharsetException e) {e.printStackTrace();}}rBody = buffer.clone().readString(charset);
//            Logger.d("===business==响应体==="+rBody);Log.d(REQUEST_TAG + "返回值", rBody);} catch (IOException e) {e.printStackTrace();}}
}

3.2.4.ResponseConverterFactory处理服务器返回数据将数据转换成对象


/*** 处理服务器返回数据* 将数据转换成对象** @author shizhiyin*/
public class ResponseConverterFactory extends Converter.Factory {private final Gson mGson;public ResponseConverterFactory(Gson gson) {this.mGson = gson;}public static ResponseConverterFactory create() {return create(new Gson());}public static ResponseConverterFactory create(Gson gson) {if (gson == null) throw new NullPointerException("gson == null");return new ResponseConverterFactory(gson);}@Overridepublic Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {return new BaseResponseBodyConverter(type);}@Overridepublic Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {return GsonConverterFactory.create().requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);}private class BaseResponseBodyConverter<T> implements Converter<ResponseBody, T> {private Type mType;private BaseResponseBodyConverter(Type mType) {this.mType = mType;}@Overridepublic T convert(ResponseBody response) {Object object;try {String strResponse = response.string();if (TextUtils.isEmpty(strResponse)) {throw new HttpException("返回值是空的—-—");}if (HttpFactory.httpResponseInterface == null) {throw new HttpException("请实现接口HttpResponseInterface—-—");} else {
//                    String strData = HttpFactory.httpResponseInterface.getResponseData(mGson, strResponse);
//                    Logger.d("==login返回值是=="+strData.toString());// strResponse 保留接口返回的全部数据// strData 只保留接口返回的data数据object = mGson.fromJson(strResponse, mType);}} catch (Exception e) {throw new HttpException(e.getMessage());} finally {response.close();}return (T) object;}}
}

 3.2.5 UploadUtils 文件上传


/*** Created by shizhiyin.* Time:2023年10月16日.* Retrofit文件上传*/public class UploadUtils {private static final String FILE_NOT_NULL = "文件不能为空";private static final String FILE_PATH_NOT_NULL = "文件路径不能为空";public static MultipartBody.Part getMultipartBody(String path) {if (TextUtils.isEmpty(path)) throw new NullPointerException(FILE_PATH_NOT_NULL);File file = new File(path);if (file.exists()) {RequestBody requestFile =RequestBody.create(MediaType.parse("application/octet-stream"), file);MultipartBody.Part body =MultipartBody.Part.createFormData("imgFile", file.getName(), requestFile);return body;} else {
//      throw new NullPointerException(FILE_NOT_NULL);return null;}}public static MultipartBody.Part getMultipartBody(File file) {if (file.exists()) {RequestBody requestFile =RequestBody.create(MediaType.parse("application/octet-stream"), file);MultipartBody.Part body =MultipartBody.Part.createFormData("file", file.getName(), requestFile);return body;} else {throw new NullPointerException(FILE_NOT_NULL);}}public static List<MultipartBody.Part> getMultipartBodysForFile(List<File> files) {if (files.isEmpty()) throw new NullPointerException(FILE_NOT_NULL);MultipartBody.Builder builder = new MultipartBody.Builder();for (File file : files) {if (file.exists()) {RequestBody requestFile =RequestBody.create(MediaType.parse("application/octet-stream"), file);builder.addFormDataPart("file", file.getName(), requestFile);} else {throw new NullPointerException(FILE_NOT_NULL);}}return builder.build().parts();}public static List<MultipartBody.Part> getMultipartBodysForPath(List<String> paths) {if (paths.isEmpty()) throw new NullPointerException(FILE_PATH_NOT_NULL);MultipartBody.Builder builder = new MultipartBody.Builder();for (String path : paths) {File file = new File(path);if (file.exists()) {RequestBody requestFile =RequestBody.create(MediaType.parse("application/octet-stream"), file);builder.addFormDataPart("file", file.getName(), requestFile);} else {throw new NullPointerException(FILE_NOT_NULL);}}return builder.build().parts();}
}

3.3 request

3.3.1.ApiAddress网络请求接口地址


public interface ApiAddress {/*** 新增原生登录接口* LogingResponseBean*/@POST("auth/login")Observable<LogingResponseBean> LoginPost(@Body JSONObject parmas);
}

3.3.2.HttpFactory网络请求


/*** @author shizhiyin* 网络请求*/
public class HttpFactory {public static String HTTP_HOST_URL = "";public static HttpResponseInterface httpResponseInterface = null;private HttpFactory() {}/*** 设置HttpClient*/private static OkHttpClient HTTP_CLIENT =new Builder()//添加自定义拦截器.addInterceptor(new HttpInterceptor()).addInterceptor(new AddCookiesInterceptor())//设置超时时间.connectTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();private static Retrofit retrofit = null;public static <T> T getChangeUrlInstance(String url, Class<T> service) {return new Retrofit.Builder().baseUrl(url).addConverterFactory(ResponseConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).client(HTTP_CLIENT).build().create(service);}public static <T> T getInstance(Class<T> service) {if (retrofit == null) {retrofit = new Retrofit.Builder().baseUrl(HTTP_HOST_URL).addConverterFactory(ResponseConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).client(HTTP_CLIENT).build();}return retrofit.create(service);}@SuppressWarnings("unchecked")public static <T> ObservableTransformer<T, T> schedulers() {return new ObservableTransformer<T, T>() {@Overridepublic ObservableSource<T> apply(Observable<T> upstream) {return upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());}};}
}

3.3.3HttpRequest


/*** @author shizhiyin*/
public class HttpRequest {private static ApiAddress Instance;public static ApiAddress getInstance() {if (Instance == null) {synchronized (HttpRequest.class) {if (Instance == null) {Instance = HttpFactory.getInstance(ApiAddress.class);}}}return Instance;}public static ApiAddress getInstance(String url) {return HttpFactory.getChangeUrlInstance(url, ApiAddress.class);}}

3.3.4ServerAddress


/*** 服务器地址** @author shizhiyin*/
public class ServerAddress {public static final String API_DEFAULT_HOST = "https://........com/";
}

四、使用

4.1.在应用的applacation中初始化

/*** 请求配置*/public static void setHttpConfig() {HttpFactory.HTTP_HOST_URL = ServerAddress.getApiDefaultHost();HttpFactory.httpResponseInterface = (gson, response) -> {if (firstOpen) {firstOpen = false;return response;}HttpBaseResponse httpResponse = gson.fromJson(response, HttpBaseResponse.class);if (httpResponse.errorCode != 0) {throw new HttpException(httpResponse.errorCode, httpResponse.errorMsg);}return gson.toJson(httpResponse.data);};}

4.2.请求示例

 private void login(String name, String pwd) {LoginRequestBean loginRequestBean = new LoginRequestBean(name, pwd);HttpRequest.getInstance(ServerAddress.BASE_URL).LoginPost((JSONObject) JSON.toJSON(loginRequestBean)).compose(HttpFactory.schedulers()).subscribe(new HttpDisposable<LogingResponseBean>() {@Overridepublic void success(LogingResponseBean bean) {}@Overridepublic void onError(Throwable e) {super.onError(e);Logger.d("====login=登录onError==" + e.toString());}});}

最后要感谢玩Android开源平台提供的参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/208310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM虚拟机:执行Java程序并指定JVM参数

本文重点 在前面我们设置参数值的时候&#xff0c;需要在eclipse中的VM中进行参数设置&#xff0c;查询的时候需要先jps&#xff0c;然后jinfo。这里尝试动态的设置和查询&#xff0c;也就是说在运行程序的时候就对其进行设置&#xff0c;并且进行查询。 过程 为了确定参数修…

微信个人号机器人开发

简要描述&#xff1a; 取消消息接收 请求URL&#xff1a; http://域名地址/cancelHttpCallbackUrl 请求方式&#xff1a; POST 请求头Headers&#xff1a; Authorization&#xff1a;login接口返回Content-Type&#xff1a;application/json 无参数 返回数据&#xff…

MeteoInfo-Java解析与绘图教程

MeteoInfo-Java解析与绘图教程(四) 上文我们说到,将地图叠加在色斑图上,但大部分都是卫星绘图,现在开始讲解micaps数据绘图,同样也是更多自定义 配置 首先我们解析micaps数据,将之前学到的东西拿过来绘图 MeteoDataInfo meteoDataInfo new MeteoDataInfo(); meteoDataInfo.o…

使用Binding的RelativeSource

一个Binding有明确的数据来源 可以通过Source或ElementName赋值的方法让Binding与之关联 但是有的时候我们不能确定作为Source的对象叫什么名字&#xff0c;但知道它与作为Binding目标的对象在UI上有相对关系&#xff0c;比如&#xff1a;空间自己关联自己的某个数据、关联自己…

Flutter代码补全

有的时候属性不经常使用&#xff0c;就想不起来该用啥&#xff0c;只有点点印象&#xff1b;只能用代码补全功能&#xff0c;但我用了AS的默认操作发下并不好使&#xff0c;估计是快捷键冲突了。刚开始是不是下面的效果&#xff1a;这肯定不是我们想要的。 不怕&#xff0c;接下…

【S32DS报错】-2-提示Error while launching command:arm-none-eabi-gdb –version错误

目录 1 Error错误提示 2 Error错误原因 3 如何消除Error错误 结尾 【S32K3_MCAL从入门到精通】合集&#xff1a; S32K3_MCAL从入门到精通https://blog.csdn.net/qfmzhu/category_12519033.html 1 Error错误提示 使用S32DSJ-LinK下载程序&#xff0c;在Dedug Configurati…

计算机基础知识67--BBS

迁移表格 # 以后你写的每个python项目&#xff0c;都必须有一个txt文件叫 requirements.txt,里面放了当前项目所有的依赖&#xff0c;别人拿到项目---》需要执行 pip install -r requirements.txt # 装好该项目所有依赖 django3.2.20 # 模块 pillow mysqlclient # 主体项目功…

中东电商指南分享!盘点中东四大跨境电商平台

提到跨境电商新蓝海&#xff0c;就不得不想起土豪聚集地 ——中东&#xff0c;中东地区拥有庞大的人口、高人均GDP、强大的消费能力以及广泛普及的互联网&#xff0c;但外出购物却相对不便&#xff0c;正是这一特点为中东跨境电商市场创造了巨大的优势。随着中东地区电商的崛起…

Gan论文阅读笔记

GAN论文阅读笔记 2014年老论文了&#xff0c;主要记录一些重要的东西。论文链接如下&#xff1a; Generative Adversarial Nets (neurips.cc) 文章目录 GAN论文阅读笔记出发点创新点设计训练代码网络结构代码测试代码 出发点 Deep generative models have had less of an impac…

软件压力测试的重要性与用途

在当今数字化的时代&#xff0c;软件已经成为几乎所有行业不可或缺的一部分。随着软件应用规模的增加和用户数量的上升&#xff0c;软件的性能变得尤为关键。为了确保软件在面对高并发和大负载时仍然能够保持稳定性和可靠性&#xff0c;软件压力测试变得至关重要。下面是软件压…

提醒事项日历同步怎么设置?可实时同步日历的提醒事项工具

随着生活节奏的加快&#xff0c;我们每天都需要处理许多琐碎的事务。为了不忘记重要的事情&#xff0c;很多人选择使用提醒事项工具来帮助自己。然而&#xff0c;市场上的提醒事项工具五花八门&#xff0c;有些并不具备日历月视图功能&#xff0c;也无法与手机日历同步&#xf…

Linux学习笔记7-IIC的应用和AP3216C

接下来进入其他两种串行通信方式&#xff1a;SPI和I2C的学习&#xff0c;因为以后的项目中会用到这些通信方式&#xff0c;而且正点原子的开发板里面也有用I2C和SPI通信的传感器来做实例&#xff0c;分别是一个距离传感器和六轴陀螺仪&#xff0c;这样就可以很好的通过实例来学…

GRE与顺丰圆通快递盒子

1. DNS污染 随想&#xff1a; 在输入一串网址后&#xff0c;会发生如下变化如果你在系统中配置了 Hosts 文件&#xff0c;那么电脑会先查询 Hosts 文件如果 Hosts 里面没有这个别名&#xff0c;就通过域名服务器查询域名服务器回应了&#xff0c;那么你的电脑就可以根据域名服…

【LeetCode:1466. 重新规划路线 | DFS + 图 + 树】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Vue 子路由页面发消息给主路由页面 ,实现主页面显示子页面的信息

需求 子页面进入后&#xff0c;能在主页面显示子页的相关信息&#xff0c;比如说主页面的菜单激活的是哪个子页面的菜单项 如上图&#xff0c;当刷新浏览器页面时&#xff0c;让菜单的激活项仍保持在【最近浏览】。 实现方式&#xff1a; 在子页面的create事件中增加&#xff…

Vue:绘制图例

本文记录使用Vue框架绘制图例的代码片段。 可以嵌入到cesium视图中,也可以直接绘制到自己的原生系统中。 一、绘制图例Vue组件 <div v-for="(color, index) in colors" :key="index" class="legend-item"><div class="color-…

深度学习还可以从如下方面进行创新!!

文章目录 一、我认为可以从如下5个方向进行创新总结 一、我认为可以从如下5个方向进行创新 新的模型结构&#xff1a;尽管现在的深度学习模型已经非常强大&#xff0c;但是还有很多未被探索的模型结构。探索新的模型结构可以带来更好的性能和更低的计算成本。 新的优化算法&a…

一个简单的postman设置断言,为何会难住一个工作5年的测试?

postman设置断言 作为一款接口测试工 具&#xff0c;postman需要对发送请求后返回的结果是否正确做验证&#xff0c;在postman中通过 tests页签做请求的验证&#xff0c;也称为断言。 postman设置断言的流程 1、在tests页签截取要对比的实际响应信息&#xff08;响应头、响应…

眼花缭乱的ADN/ADX/DSP/DMP/SSP和他们的关系链

做过互联网广告尤其是程序化广告的同学都遇到过以下这些名词&#xff0c;或许正被他们折磨的焦头烂额&#xff0c;这篇文章&#xff0c;我们就来说说这些概念的含义及他们之间的关系链。 ADN&#xff1a;AD Network——广告网络或广告联盟。连接广告主和媒体的中间商。 ADX&…

stm32串口编程实例-实现数据的收发功能

大家好&#xff0c;今天给大家介绍stm32串口编程实例&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 串口是USART(通用同步/异步收发器)的俗称。 实际上&#xff0c;串行总线并不…