# 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 ;