# RxEasyHttp
**Repository Path**: hihopeorg/RxEasyHttp
## Basic Information
- **Project Name**: RxEasyHttp
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 1
- **Created**: 2021-03-05
- **Last Updated**: 2024-10-10
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## **RxEasyHttp**
本项目是基于开源项目 RxEasyHttp 进行ohos化的移植和开发的,可以通过项目标签以及github地址( https://github.com/zhou-you/RxEasyHttp )追踪到原项目版本
#### 项目介绍
* 项目名称:简单易用的网络请求框架
* 所属系列:ohos的第三方组件适配移植
* 项目移植状态:完成
* 调用差异:无
* 项目作者和维护人:hihope
* 联系方式:hihope@hoperun.com
* 原项目Doc地址:https://github.com/zhou-you/RxEasyHttp
* 原项目基线版本:无release 版本,shal:42bd5d3c9dcd4a42f6ab7d69c3fdc2ba5faf54d1
* 编程语言:java
* 外部库依赖:rxohos-release.har ,adapter-rxjava3-2.9.0.jar,retrofit-2.9.0.jar
##### 功能及特点
* 比Retrofit使用更简单、更易用。
* 采用链式调用一点到底
* 加入基础ApiService,减少Api冗余
* 支持动态配置和自定义底层框架Okhttpclient、Retrofit.
* 支持多种方式访问网络GET、POST、PUT、DELETE等请求协议
* 支持网络缓存,八种缓存策略可选,涵盖大多数业务场景
* 支持固定添加header和动态添加header
* 支持添加全局参数和动态添加局部参数支持文件下载、多文件上传和表单提交数据
* 支持文件请求、上传、下载的进度回调、错误回调,也可以自定义回调
* 支持默认、全局、局部三个层次的配置功能支持任意数据结构的自动解析
* 支持添加动态参数例如timeStamp时间戳、token、签名sign
* 支持自定义的扩展API
* 支持多个请求合并支持Cookie管理支持异步、同步请求
* 支持Https、自签名网站Https的访问、双向验证
* 支持失败重试机制,可以指定重试次数、重试间隔时间
* 支持根据ky删除网络缓存和清空网络缓存提供默认的标准ApiResult解析和回调,并且可自定义ApiResult
* 支持取消数据请求,取消订阅,带有对话框的请求不需要手动取消请求,对话框消失会自动取消请求
* 支持请求数据结果采用回调和订阅两种方式api设计上结合http协议和ohosd平台特点来实现,loading对话框,实时进度条显示返回结果和异常统一处理结合RxJava3,线程智能控制
#### 效果展示图
#### 安装教程
方法(一)
1. 下载RxEasyHttp的依赖包 rxohos-release.har ,json-lib-2.4-jdk15.jar,adapter-rxjava3-2.9.0.jar,retrofit-2.9.0.jar,。
2. 启动 DevEco Studio,将下载的jar包,导入工程目录“entry->libs”下。
3. 在moudle级别下的build.gradle文件中添加依赖,在dependences标签中增加对libs目录下jar包的引用。
4. 在导入的jar包上点击右键,选择“Add as Library”对包进行引用,选择需要引用的模块,并点击“OK”即引用成功。
```
implementation fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
implementation files("./libs/retrofit-2.9.0.jar")
annotationProcessor files("./libs/retrofit-2.9.0.jar")
implementation files('./libs/rxohos-release.har')
annotationProcessor files("./libs/rxohos-release.har")
...
```
方法(二)
1.在工程的build.gradle的allprojects中,添加HAR所在的Maven仓地址
```
repositories {
maven {
url 'http://106.15.92.248:8081/repository/Releases/'
}
}
```
2.在应用模块的build.gradle的dependencies闭包中,添加如下代码:
```
dependencies {
implementation 'com.zhouyou.ohos:rxeasyhttp:1.0.1'
}
```
#### 使用说明
##### 1.默认初始化
在MyApplication 可以如下代码:
```
@Overridepublic void onInitialize() {
super.onInitialize();
EasyHttp.init(this);
}
```
##### 2.高级初始化
```
package com.zhouyou.http.demo;import com.zhouyou.http.EasyHttp;
import com.zhouyou.http.cache.converter.SerializableDiskConverter;
import com.zhouyou.http.demo.constant.AppConstant;
import com.zhouyou.http.demo.interceptor.CustomSignInterceptor;
import com.zhouyou.http.model.utils.SystemInfoUtils;
import com.zhouyou.http.model.HttpHeaders;
import com.zhouyou.http.model.HttpParams;
import com.zhouyou.http.utils.HttpLog;
import ohos.aafwk.ability.AbilityPackage;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
public class MyApplication extends AbilityPackage {
public static MyApplication context=null;
@Override
public void onInitialize() {
super.onInitialize();
context=this;
EasyHttp.init(this);
//这里涉及到安全我把url去掉了,demo都是调试通的
String Url = "http://www.xxx.com";
//设置请求头
HttpHeaders headers = new HttpHeaders();
headers.put("User-Agent", SystemInfoUtils.getUserAgent(this,
AppConstant.APPID));
//设置请求参数
HttpParams params = new HttpParams();
// params.put("appId", AppConstant.APPID);
EasyHttp.getInstance()
.debug("RxEasyHttp", BuildConfig.DEBUG)
.setReadTimeOut(60 * 1000)
.setWriteTimeOut(60 * 1000)
.setConnectTimeout(60 * 1000)
.setRetryCount(3)//默认网络不好自动重试3次
.setRetryDelay(500)//每次延时500ms重试
.setRetryIncreaseDelay(500)//每次延时叠加500ms
.setBaseUrl(Url)
.setCacheDiskConverter(new SerializableDiskConverter())//默认缓存使用序列化转化
.setCacheMaxSize(50 * 1024 * 1024)//设置缓存大小为50M
.setCacheVersion(1)//缓存版本为1
.setHostnameVerifier(new UnSafeHostnameVerifier(Url))//全局访问规则
.setCertificates()//信任所有证书
// .addConverterFactory(GsonConverterFactory.create(gson))//本框架没有采用Retrofit的Gson转化,所以不用配置
.addCommonHeaders(headers)//设置全局公共头
.addCommonParams(params)//设置全局公共参数
.addInterceptor(new CustomSignInterceptor());//添加参数签名拦截器//
.addInterceptor(new HeTInterceptor());//处理自己业务的拦截器
}
public class UnSafeHostnameVerifier implements HostnameVerifier {
private String host;
public UnSafeHostnameVerifier(String host) {
this.host = host;
HttpLog.i("############### UnSafeHostnameVerifier " + host);
}
@Override
public boolean verify(String hostname, SSLSession session) {
HttpLog.i("############### verify " + hostname + " " + this.host);
if (this.host == null || "".equals(this.host) |!this.host.contains(hostname)) return false;
return true;
}
}
}
```
##### 3.使用实例
初始sample的构建
```
public class DownloadAbilitySlice extends AbilitySlice {
private HorizontalProgressDialog dialog;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_download);
dialog = new HorizontalProgressDialog(this);
dialog.setMessage("正在下载...");
// 设置提示的title的图标,默认是没有的,如果没有设置title的话只设置Icon是不会显示图标的
dialog.setTitle("下载文件");
dialog.setMax(100);
findComponentById(ResourceTable.Id_btn_down_loade_file1).setClickedListener(component -> { onDownloadFile1(); });
findComponentById(ResourceTable.Id_btn_down_load_file2).setClickedListener(component -> { onDownloadFile2(); });
}
public void onDownloadFile1() {
//下载回调是在异步里处理的
dialog = new HorizontalProgressDialog(this);
EasyHttp.downLoad("http://apk.hiapk.com/web/api.do?qt=8051&id=723")
//EasyHttp.downLoad("http://crfiles2.he1ju.com/0/925096f8-f720-4aa5-86ae-ef30548d2fdc.txt")
.savePath(FileUtils.getDistDir(this) + "test/")
.saveName("custom_name")//默认名字是时间戳生成的
.execute(new DownloadProgressCallBack() {
@Override
public void update(long bytesRead, long contentLength, boolean done) {
int progress = (int) (bytesRead * 100 / contentLength);
HttpLog.e(progress + "% ");
dialog.setProgress(progress);
if (done) {
dialog.setMessage("下载完成");
}
}
@Override
public void onStart() {
HttpLog.i("======" + Thread.currentThread().getName());
dialog.show();
}
@Override
public void onComplete(String path) {
ToastUtils.getInstance().showToast("文件保存路径:" + path);
dialog.dismiss();
}
@Override
public void onError(final ApiException e) {
HttpLog.i("======" + Thread.currentThread().getName());
ToastUtils.getInstance().showToast(e.getMessage());
dialog.dismiss();
}
});
}
public void onDownloadFile2() {
//String url = "http://crfiles2.he1ju.com/0/925096f8-f720-4aa5-86ae-ef30548d2fdc.txt";//
String url = "http://txt.99dushuzu.com/download-txt/3/21068.txt";
String url="http://fga1.market.xiaomi.com/download/AppStore/0b0f04f6f8473a54a1e14ce06610ecb36ae427f35/com.sysongy.sysongyportal.apk";
EasyHttp.downLoad(url)
.savePath(FileUtils.getDistDir(this) + "test/QQ")
.saveName(FileUtils.getFileName(url))
.execute(new DownloadProgressCallBack() {
@Override
public void update(long bytesRead, long contentLength, boolean done) {
int progress = (int) (bytesRead * 100 / contentLength);
HttpLog.e(progress + "% ");
dialog.setProgress(progress);
if (done) {
dialog.setMessage("下载完成");
dialog.dismiss();
}
}
// view ohos.agp.components.DirectionalLayout@faf84ac being added, but it already has a parent
@Override
public void onStart() {
if(!dialog.isShowing()){
dialog.show();
}
}
@Override
public void onComplete(String path) {
ToastUtils.getInstance().showToast("文件保存路径:" + path);
dialog.dismiss();
}
@Override
public void onError(ApiException e) {
ToastUtils.getInstance().showToast(e.getMessage());
dialog.dismiss();
}
});
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
```
##### 4.请求数据
网络请求,采用链式调用,支持一点到底。
###### 入口方法
```
/**
* get请求
*/
public static GetRequest get(String url);
/**
* post请求和文件上传
*/
public static PostRequest post(String url);
/**
* delete请求
*/
public static DeleteRequest delete(String url) ;
/**
* 自定义请求
*/
public static CustomRequest custom();
/**
* 文件下载
*/
public static DownloadRequest downLoad(String url) ;
/**
* put请求
*/
public static PutRequest put(String url);
```
##### 5.通用功能配置
1.包含一次普通请求所有能配置的参数,真实使用时不需要配置这么多,按自己的需要选择性的使用即可
2.以下配置全部是单次请求配置,不会影响全局配置,没有配置的仍然是使用全局参数。
3.为单个请求设置超时,比如涉及到文件的需要设置读写等待时间多一点。完整参数GET示例:
```
EasyHttp.get("/v1/app/chairdressing/skinAnalyzePower/skinTestResult")
.baseUrl("http://www.xxxx.com")//设置url
.writeTimeOut(30*1000)//局部写超时30s,单位毫秒
.readTimeOut(30*1000)//局部读超时30s,单位毫秒
.connectTimeout(30*1000)//局部连接超时30s,单位毫秒
.headers(new HttpHeaders("header1","header1Value"))//添加请求头参数
.headers("header2","header2Value")//支持添加多个请求头同时添加
.headers("header3","header3Value")//支持添加多个请求头同时添加
.params("param1","param1Value")//支持添加多个参数同时添加
.params("param2","param2Value")//支持添加多个参数同时添加
//.addCookie(new CookieManger(this).addCookies())//支持添加Cookie
.cacheTime(300)//缓存300s 单位s
.cacheKey("cachekey")//缓存key
.cacheMode(CacheMode.CACHEANDREMOTE)//设置请求缓存模式
//.okCache()//使用模式缓存模式时,走Okhttp缓存
.cacheDiskConverter(new GsonDiskConverter())//GSON-数据转换器
//.certificates()添加证书
.retryCount(5)//本次请求重试次数
.retryDelay(500)//本次请求重试延迟时间500ms
.addInterceptor(Interceptor)//添加拦截器
.okproxy()//设置代理
.removeHeader("header2")//移除头部header2
.removeAllHeaders()//移除全部请求头
.removeParam("param1")
.accessToken(true)//本次请求是否追加token
.timeStamp(false)//本次请求是否携带时间戳
.sign(false)//本次请求是否需要签名
.syncRequest(true)//是否是同步请求,默认异步请求。true:同步请求
.execute(new CallBack() {
@Override
public void onStart() {
//开始请求
}
@Override
public void onCompleted() {
//请求完成
}
@Override
public void onError(ApiException e) {
//请求错误
}
@Override
public void onSuccess(SkinTestResult response) {
//请求成功
}
});
```
**url**
Url可以通过初始化配置的时候传入
```
EasyHttp.getInstance().setBaseUrl("http://www.xxx.com");
```
入口方法传入:
```
EasyHttp.get("/v1/app/chairdressing/skinAnalyzePower/skinTestResult").baseUrl("http://www.xxxx.com")
```
如果入口方法中传入的url含有http或者https,则不会拼接初始化设置的baseUrl. 例如:
EasyHttp.get("http://www.xxx.com/v1/app/chairdressing/skinAnalyzePower/skinTestResult")则setBaseUrl()和baseUrl()传入的baseurl都不会被拼接。 注:EasyHttp.get/post/put/等采用拼接的用法时请注意,url要用/斜杠开头,例如:EasyHttp.get("/v1/login") 正确 EasyHttp.get("v1/login") 错误
**http请求参数**
.headers(HttpHeaders headers) .headers("header2","header2Value")//添加参数键值对
.addCommonHeaders(headers)//设置全局公共头
##### 6.普通网络请求
支持get/post/delete/put等 链式调用的终点请求的执行方式有:execute(Class clazz) 、execute(Type type)、execute(CallBack callBack)三种方式,都是针对标准的ApiResult
**execute(CallBack callBack)**
1.EasyHttp(推荐) 示例:
```
方式一:
//EasyHttp.post("/v1/app/chairdressing/skinAnalyzePower/skinTestResult")
EasyHttp.get("/v1/app/chairdressing/skinAnalyzePower/skinTestResult")
.readTimeOut(30 * 1000)//局部定义读超时
.writeTimeOut(30 * 1000)
.connectTimeout(30 * 1000)
.params("name","张三")
.timeStamp(true)
.execute(new SimpleCallBack() {
@Override
public void onError(ApiException e) {
showToast(e.getMessage());
}
@Override
public void onSuccess(SkinTestResult response) {
if (response != null) showToast(response.toString());
}
});
```
2.手动创建请求对象
```
//GetRequest 、PostRequest、DeleteRequest、PutRequest
GetRequest request = new GetRequest("/v1/app/chairdressing/skinAnalyzePower/skinTestResult");
request.readTimeOut(30 * 1000)//局部定义读超时
.params("param1", "param1Value1")
.execute(new SimpleCallBack() {
@Override
public void onError(ApiException e) {
}
@Override
public void onSuccess(SkinTestResult response) {
}
});
```
#### 版本迭代
version 1.0.1
#### 版权和许可信息
Licensed under the Apache License, Version 2.0 ;