当前位置: 首页 > 编程日记 > 正文

x-http-wrapper: 如何解决每次发版时,修改http相关代码造成的错误!(Android、iOS、h5)...

其实是我做了个开源工具(^__^),拿出来给大家鉴赏下,欢迎大家提意见
项目:github.com/xuyt11/x-ht… 欢迎关注和star 。
功能:这是一个http相关代码的创建工具。

现在我们每一次发版,基本上都会涉及到http相关的修改,以此来满足发版的业务需求。
而在其中需要添加或修改的有http request、http request param、http response entity等其他相关的http代码。
而在多次的修改中,若前后端没有协调好,就有可能会造成之后的返工、重复修改与线上bug量的增加等问题。

现在的痛点

如何解决每次发版时,都需要新增、修改http相关代码!
如何解决每次发版时,修改http相关代码造成的错误!

解决思路: 规范

  1. 其实很简单,就是一个词“规范”,任何事情,只要我们有了一定的规范,就会有一定的流程、可追踪并且降低难度。
    我相信99.99%的公司,都会有相关的http接口文档提供给前端同学,而且也会自己的一套规范(不论是我现在依赖的apidocjs,还是上家公司的doc文件)。
    当然,肯定也有口头约定的情况,但这需要在之后,立即将约定转化为文档,提供给前端的同学。git、http都可以作为提供的形式。

  2. 我们依赖这个http的规范,就可以将http接口文档去解析转义为x-http-wrapper内部的API数据。

  3. 再来就是依赖一定的规范(x-http-wrapper的模板文件规范),将内部API数据转化为http相关文件。这样,每次只要接口文档更新过后,我们就可以根据文档生成各个程序内部可以运行的代码。
    这个功能与现在IDE中的getter、setter方法生成器功能其实是相同的原理!

x-http-wrapper介绍

  1. 这是一个http相关代码的创建工具。
  2. 现在能创建的http相关的文件类型有:http请求分类,http请求,请求方法参数,响应实体,响应实体中状态码列表和基础响应实体类。

    • HttpApi(http请求分类): 所有API请求的统一调用入口,统合所有的请求类别的接口,防止API接口分散。

      public class HttpApi {private static Account account;private static Data data;private static Message message;public static Account account() {if (null == account) {account = Account.getInstance();}return account;}public static Data data() {if (null == data) {data = Data.getInstance();}return data;}public static Message message() {if (null == message) {message = Message.getInstance();}return message;}
      }复制代码
    • Request(http请求): 单个请求分组中,所有的请求方法。

      public class Account extends BaseApi {public static Account getInstance() {return Helper.instance;}private static class Helper {public static final Account instance = new Account();}private Account() {super();}/*** @version 2.0.0* @requestUrl * @title 初始化账号信息**/public RequestHandle init(Context cxt001,ResponseHandlerInterface response) {// hide implementation}/*** @version 2.0.0* @title 扫二维码到 web 端进行操作** @param context String desc* @param project_id isOptional Integer desc* @param scene isOptional String desc* @param uuid_rand String desc*/public RequestHandle qrcodeConfirm(Context cxt001,String context, Integer project_id, String scene, String uuid_rand, ResponseHandlerInterface response) {// hide implementation}/*** 缩略请求方法*/public RequestHandle qrcodeConfirm(Context cxt001,QrcodeConfirmRP.Parameter parameter, ResponseHandlerInterface response) {return qrcodeConfirm(cxt001,parameter.context, parameter.project_id, parameter.scene, parameter.uuid_rand, response);}}复制代码
    • RequestParam(请求方法参数): 请求参数分组归类,对应单个请求,用于请求参数较多的情况,生成请求参数的分类实体类(请求参数也肯能有多个分类),减少请求方法的输入参数。

      /**
      * 请求方法参数
      */
      public class QrcodeConfirmRP implements Serializable {public static final class Parameter implements Serializable {/*** type: String<br>* isOptional : false<br>* desc: <p>扫码场景,枚举值</p>*/public String context;/*** type: Integer<br>* isOptional : true<br>* desc: <p>业务参数: 根据 context 的不同而不同</p>*/public Integer project_id;/*** type: String<br>* isOptional : true<br>* desc: <p>身份信息: 服务端会优先使用客户端传入的身份信息,当为”投资人“的时候必传</p>*/public String scene;/*** type: String<br>* isOptional : false<br>* desc: <p>从二维码扫描得到的唯一码</p>*/public String uuid_rand;}}复制代码
    • Response(响应实体): 请求的相应数据model

      public class Init {private long member_id;private long member_role;private long member_status;private String ry_token;private long step;public long getMemberId() {return member_id;}public long getMemberRole() {return member_role;}public long getMemberStatus() {return member_status;}public String getRyToken() {return ry_token;}public long getStep() {return step;}public void setMemberId(long member_id) {this.member_id = member_id;}public void setMemberRole(long member_role) {this.member_role = member_role;}public void setMemberStatus(long member_status) {this.member_status = member_status;}public void setRyToken(String ry_token) {this.ry_token = ry_token;}public void setStep(long step) {this.step = step;}}复制代码
    • StatusCode(响应实体中状态码列表): 响应中所有状态码的枚举类

      public class StatusCode {/** '') */public static final int OK = 0;/** '登录状态已过期,请重新登入') */public static final int UNAUTHORIZED = 101;/** '您没有权限查看') */public static final int FORBIDDEN = 102;/** '资源未找到') */public static final int NOT_FOUND = 103;/** '客户端请求错误') # 4XX客户端错误 */public static final int CLIENT_ERROR = 228;/** '服务器错误') # 5XX 服务器错误 */public static final int SERVER_ERROR = 229;/** '参数错误') */public static final int PARAM_ERROR = 230;/** '登录失败,请检查您的邮箱地址是否正确') */public static final int LOGIN_FAIL_EMAIL_NOT_EXIST = 332;/** '登录失败,请确认您的手机号是否正确') */public static final int LOGIN_FAIL_MOBILE_NOT_EXIST = 333;/** '登录失败,请检查密码是否正确') */public static final int LOGIN_FAIL_PASSWORD_ERROR = 334;}复制代码
    • BaseResponse(基础响应实体类): 基础的响应实体类

      public class ResponseEntity<T> {private int status_code;private String message;private Error error;private T data;public int getStatusCode() {return status_code;}public void setStatusCode(int status_code) {this.status_code = status_code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Error getError() {return error;}public void setError(Error error) {this.error = error;}public T getData() {return data;}public void setData(T data) {this.data = data;}public static class Error {private String detail;private List<String> device_token;private List<String> content;private List<String> followed_id;public String getDetail() {return detail;}public void setDetail(String detail) {this.detail = detail;}public List<String> getDeviceToken() {return device_token;}public void setDeviceToken(List<String> device_token) {this.device_token = device_token;}public List<String> getContent() {return content;}public void setContent(List<String> content) {this.content = content;}public List<String> getFollowedId() {return followed_id;}public void setFollowedId(List<String> followed_id) {this.followed_id = followed_id;}}}复制代码
  3. http的数据来源,现阶段只有apidocjs这一个
    • 若有其他数据来源,可以配置api_data.source属性,然后添加对应的解析器,解析为xhw的model。

工具环境与依赖

  • 命令行运行jar文件: 需要java8及以上的版本
  • 开发环境:
    • Java的版本: java8及以上的版本
    • 开发平台: intellij idea
    • 依赖的jar: gson:2.8.0, rxjava:1.2.2, junit:4.12

快速使用入门

  1. 下载项目的Zip包,解压缩,从xhwt文件夹下,选取其中的一个包装器模板文件夹,作为目标包装器的配置,该文件夹在下面都叫做target dir
    • 例如:xhwt/asynchttp/non_version(这是android-async-http库的一个模板与配置);
  2. 获取接口数据文件(api_data.json:存储apidocjs生成的API文档的数据)的路径;
    • 例如:guide文件夹中的api_data.json的绝对路径
  3. 修改target dir下配置文件(x-http-wrapper.json)中api_data.file_path_infos的配置信息,将api_data.json的绝对路径添加上去;
       "api_data": {"source": "apidocjs","file_path_type": "file","file_path_infos": [{"os_name": "Mac OS X","path": "api_data.json的绝对路径"},{"os_name": "Windows","path": "api_data.json的绝对路径"}],"file_charset": "UTF-8"}复制代码
  4. 修改target dir中,API的模板文件中\\标签内,生成文件的目标路径;
    • API的模板文件是以.xhwt为后缀的文件,是生成各个http相关文件的模板;
    • \\标签内,保存的是模板文件生成文件的文件名称与文件地址;
      • 例如:
        {"file_name":"HttpApi.swift","file_dirs":[{"os_name":"Windows","path":"生成文件的目标路径(绝对路径)"},{"os_name":"Mac OS X","path":"生成文件的目标路径(绝对路径)"}]
        }复制代码
  5. 修改target dir下配置文件(x-http-wrapper.json)中template_file_infos中的need_generate属性,用于开启、关闭生成文件的功能;
    • 例如:若你想生成HttpApi类型的文件,就需要将template_file_infos.HttpApi.need_generate设置为true,并要修改了xxx-httpapi.xhwt文件中header标签内的地址;
      "template_file_infos": {"HttpApi": {"need_generate": true,"path": "ncm_ios_n-httpapi.xhwt"},...
      }复制代码
  6. 命令行生成相关http文件
    • 命令行运行:java -jar (jar文件的路径) (配置文件的绝对路径)
    • jar文件的路径:在guide文件夹下有最新的jar(x-http-wrapper.jar)
    • 配置文件的绝对路径:配置文件(x-http-wrapper.json)的绝对路径
      java -jar x-http-wrapper.jar xxxx/x-http-wrapper.json复制代码

api的数据源:apidocjs

  • api_data.json就是使用apidocjs工具生成的数据文件;

工作流程

  1. 解析x-http-wrapper.json这个配置文件;
  2. 在配置文件中,有API数据文件(在api_data中),再根据配置数据,将API数据解析为x-http-wrapper中的model数据;
  3. 在配置文件中,有所有的x-http-wrapper的template文件(在template_file_infos中),根据template文件中的内容与model datas和配置一起,生成目标文件;

最新的jar

  1. 使用方式:
    java -jar x-http-wrapper.jar xxx/x-http-wrapper.json复制代码
  2. x-http-wrapper.json文件,必须是绝对路径,该文件是整个wrapper的配置文件;
  3. 若有多个json文件,也可以(如:有多个程序(ios,android)需要生成代码);

wrapper的配置文件:

  • x-http-wrapper.json (详细的配置文件介绍)
  • 该文件保存有所有的配置信息, 共有8个分类:
    api_data, template_file_infos, base_config, filter, request, response, status_code, param_types

wrapper内部api数据模型

  1. BaseModel:
    • 所有的model都需要继承BaseModel
    • BaseModel中有一个泛型用于存储更高一级的BaseModel
    • 在template engine中,反射只认BaseModel,不是BaseModel的model不能反射
    • template engine在反射调用时,若没有在反射的对象中找到方法,会从higherLevel中去找,直到没有higherLevel为止;
  2. model的结构:
    • VersionModel-->StatusCodeGroup, RequestGroup
    • StatusCodeGroup-->StatusCode
    • RequestGroup-->Request-->Url,Header,Input,Response
    • Response-->Response File,Response Message

wrapper模板文件的类型

  1. 所有的类别都在XHWTFileType枚举中,现阶段共有6个类别;
    • HttpApi, Request, RequestParam, Response, StatusCode, BaseResponse
  2. 且在该枚举中也有该模板类别所需数据的获取过滤功能(getReflectiveDatas方法);

wrapper模板标签

  1. 生成的文件内容由该文件类型获取到的API数据与标签两者来驱动
  2. 头部标签\\: 用于标示该模板文件,生成的目标文件路径和名称;
    • file_dirs:目标文件路径
    • file_name:目标文件名称
  3. 现阶段只有7个标签类型:使用反射来进行数据的加工
    • text, foreach, retain, list_single_line, if_else, list_replace, list_attach
    • 标签内部的匹配都为反射的方法名称;
      • 例如:在foreach标签中
        <t:foreach each="request_groups">
        </t:foreach>复制代码
        匹配的request_groups即为反射后去request_groups方法的数据,然后利用该数据去遍历;

相关文章:

设计一款编程语言有多难?

作者 | DAVID CASSEL译者 | 弯月&#xff0c;责编 | 郑丽媛题图 | 自视觉中国来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;最近&#xff0c;Ruby编程语言的创始人兼主设计师、云平台即服务公司Heroku的Ruby首席架构师松本行弘在一次演讲中表示&#xff0c;由松本…

在 DW 中插入 Flash 的参数详解

作者&#xff1a;macromedia 文章来源&#xff1a; 蓝色理想 在Dreamweaver中插入FLASH后还可以有很多的控制参数&#xff0c;点属性面板右下的参数钮&#xff0c;就会有参数和值的加入。大家可以自由的控制&#xff0c; 以下内容摘自 Flash MX 2004 帮助文档 参数和属性下…

C语言中文件的读写(fputc和fgetc)(putchar和getchar)

文件打开之后就可以对文件进行读写了。 1、fputc(ch,fp); 将字符ch输出到&#xff08;即写到&#xff09;fp所指向的文件中。如果输出成功&#xff0c;返回字符ch的值&#xff0c;否则返回EOF&#xff08;-1&#xff09; putchar(c) 是从fputc中派生出来的&#xff0c;在stdio.…

转 微博 linux中ctime,mtime,atime的区别

http://blog.sina.com.cn/s/blog_67178440010101gr.html 当你同熟练的UNIX用户进行交谈时&#xff0c;你经常会听到他们傲慢地讲出术语“改变时间(change time)”和“修改时间(modification time)”。对于许多人(和许多字典而言),改变和修改是相同的。这里会有什么不同那&#…

WEB 打印的相关技术分析

文/谢康 做Web开发的人员一定都会面临一个共同的难题&#xff0c;那就是打印。的确&#xff0c;相对于Windows桌面应用程序来讲&#xff0c;Web应用程序的打印有种种限制&#xff0c;技术人员在项目开发过程中经常会遇到用户这样或那样的需求. 做过桌面应用开发的人都会非常熟悉…

jquery validate使用

一、用前必备 官方网站&#xff1a;http://bassistance.de/jquery-plugins/jquery-plugin-validation/ API: http://jquery.bassistance.de/api-browser/plugins.html 当前版本&#xff1a;1.5.5 需要JQuery版本&#xff1a;1.2.6, 兼容 1.3.2 <script src"../js/jquer…

Python程序员的“避坑”指南

结合我最近这些年的Python学习、开发经验&#xff0c;发现90%的人在学Python时都会遇到下面这些问题&#xff1a;1. 没什么经验根本不知道从何学起&#xff0c;而且应用方向太多了根本不知道该选择什么方向...2. 基础入门看似简单&#xff0c;但是进阶实战就举步维艰&#xff0…

java web项目流程小结

java web项目从发出请求到返回结果流程整理&#xff1a;客户发出请求&#xff0c;通过web.xml 中配置的DispatchServlet接收请求并调用 handlerMapping 将请求分发到对应的Controller,Controller调service&#xff0c;service调dao,dao层根据方法名对应到sql.xml&#xff0c;通…

snmp在企业网中的应用

一.snmp简介 snmp概念 SNMP(Simple Network Management Protocol,简单网络管理协议)的前身是简单网关监控协议(SGMP)&#xff0c;用来对通信线路进行管理。随后&#xff0c;人们对SGMP进行了很大的修改&#xff0c;特别是加入了符合Internet定义的SMI和MIB&#xff1a;体系结构…

浅谈在ASP.NET中数据有效性校验的方法

作者&#xff1a;未知作为一名程序员&#xff0c;一定要对自己编写的程序的健壮性负责&#xff0c;因此数据的校验无论在商业逻辑还是系统实现都是必不可少的部分。我这里总结了一种自认为比较不错的asp.net&#xff08;C#&#xff09;的数据校验方法&#xff0c;如大家探讨。主…

关于Python 3.9,那些你不知道的事

作者 | Ayushi Rawat编译 | 高卫华题图 | 视觉中国Python一直在满足社区需求&#xff0c;并且将成为未来使用最多的语言。Python的下一个版本带来了更快速的进程释放&#xff0c;性能的提升&#xff0c;简便的新字符串函数&#xff0c;字典并集运算符以及更兼容稳定的内部API。…

memcache缓存失效

缓存过期 memcached在处理过期的缓存项时&#xff0c;采用懒惰模式处理方法。 缓存项过期&#xff0c;不会立即删除&#xff0c;直到对该缓存项执行了get操作&#xff0c;才会删除过期缓存。> set key 0 10 > test > stats //查看curr_items的值 > get key //超过过…

ASP.NET HTTP 运行时

ASP.NET HTTP 运行时一个请求从 URL 字符串到 HTML 代码的“漫长曲折”之路 Dino EspositoWintellect 2003年7月10日 摘要&#xff1a;本文详细介绍了 HTTP 运行时的组成部分&#xff0c;以及在处理对 ASP.NET 应用程序的各种请求时采用的逻辑。文章还以 Web Garden 模型和最新…

C++中的const关键字(zz)

【补充】mutable关键字有时我们希望类的数据成员即使在const成员函数中&#xff0c;依然是可以修改的&#xff0c;这时就可以把它们声明为mutable来实现。这样的应用&#xff0c;比如记录各种操作的调用次数&#xff0c;这时&#xff0c;即使在const中&#xff0c;依然要修改计…

Python让你成为AI 绘画大师,简直太惊艳了!(附代码))

作者 | 李秋键责编 | 李雪敬头图 | CSDN下载自视觉中国引言&#xff1a;基于前段时间我在CSDN上创作的文章“CylcleGAN人脸转卡通图”的不足&#xff0c;今天给大家分享一个更加完美的绘制卡通的项目“Learning to Cartoonize Using White-box Cartoon Representations”。首先…

Vue 2 | Part 4 v-bind绑定元素属性和样式

这期跟大家分享的&#xff0c;是v-bind指令。它可以往元素的属性中绑定数据&#xff0c;也可以动态地根据数据为元素绑定不同的样式。 绑定属性 最简单的例子&#xff0c;我们有一张图片&#xff0c;需要定义图片的src。我们可以直接在元素的属性里面定义&#xff1a; <div …

在 ASP.NET 中执行 URL 重写

在 ASP.NET 中执行 URL 重写 发布日期&#xff1a; 8/23/2004| 更新日期&#xff1a; 8/23/2004Scott Mitchell 4GuysFromRolla.com 适用范围&#xff1a; Microsoft ASP.NET 摘要&#xff1a;介绍如何使用 Microsoft ASP.NET 执行动态 URL 重写。URL 重写是截取传入 Web 请求并…

win8中使用BitLocker加密

一、加密驱动器二、管理三、TPM转载于:https://blog.51cto.com/jimshu/989359

​清华硕士爆料:这些才是机器学习必备的数学基础

现如今&#xff0c;计算机科学、人工智能、数据科学已成为技术发展的主要推动力。无论是要翻阅这些领域的文章&#xff0c;还是要参与相关任务&#xff0c;你马上就会遇到一些拦路虎&#xff1a;想过滤垃圾邮件&#xff0c;不具备概率论中的贝叶斯思维恐怕不行&#xff1b;想试…

Oracle Golden Gate体系架构详解(原创) - CzmMiao的博客生活 - ITeye技术网站

Oracle Golden Gate体系架构详解(原创) - CzmMiao的博客生活 - ITeye技术网站

用C#对ADO.NET数据库完成简单操作

作者&#xff1a;李阳 http://oraasp.vicp.net/article/article.aspx?ID21 数据库访问是程序中应用最普遍的部分。随着C#和ADO.NET的引入&#xff0c;这种操作变得更简单。这篇文章将示范四种最基础的数据库操作。 ● 读取数据。其中包括多种数据类型&#xff1a;整型&#…

用createrepo配置Yum本地源

yum配置本地源, 在网速差的情况下&#xff0c;yum用在线源是一件头痛的事&#xff0c;所以以下为yum的本地源配置可以有好解决这个事。 1,安装createrepo包&#xff0c; 可以用yum安装(yum install createrepo -y); 也可以安装rpm或tar包 &#xff08;网址&#xff1a;createre…

首次在手机端不牺牲准确率实现BERT实时推理,比TensorFlow-Lite快近8倍,每帧只需45ms...

作者 | 王言治 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 基于Transformer的预训练模型在许多自然语言处理&#xff08;NLP&#xff09;任务中取得了很高的准确度。但是这些预训练模型往往需要很大的计算量和内存。由于移动平台的存储空间以及计算能力的限制&a…

[svc]caffe安装笔记-显卡购买

caffe,这是是数据组需要做一些大数据模型的训练(深度学习), 要求 服务器显卡(运算卡), 刚开始老板让买的牌子是泰坦的(这是2年前的事情了). 后来买不到这个牌子的,(jd,tb)看过丽台的,看过gtx系列的哪个型号来着, 也不合适,后来买的特斯拉显卡 [查了下一些知名的显卡牌子](https…

AABO:自适应最优化Anchor设置,性能榨取的最后一步 | ECCV 2020

编译 | VincentLee来源 | 晓飞的算法工程笔记Introduction目前&#xff0c;主流的目标检测算法使用多种形状的anchor box作为初始预测&#xff0c;然后对anchor box进行回归调整&#xff0c;anchor box的配置是检测算法中十分重要的超参数。一般而言&#xff0c;anchor box的配…

Android列表控件选项中添加进度框ProgressBar实现

今天有时间就学习了下在ListView、GridView列表项中清加ProgressBar,小马用最简单的代码实现可以通用的功能&#xff0c;人人都能看懂&#xff0c;哈哈&#xff0c;直接说下&#xff0c;如果你的适配器getView方法返回的View是一个自定义控件的话&#xff0c;有点不好实现哦&am…

写一个通用数据访问组件

出处&#xff1a;http://www.csharp-corner.com willsound&#xff08;翻译&#xff09; 我收到过好多Email来问我如何用一个通用的数据提供者(data provider)在不失自然数据提供者(native data provider)稳定而强大功能的前提下来访问不同的数据源(data sources).一个小伙子…

InstallShield 2015 LimitedEdition VS2012 运行bat文件

转载:http://www.cnblogs.com/fengwenit/p/4271150.html 运行bat文件 网上很多介绍如何运行bat的方法&#xff0c;但我这个是limted 版本&#xff0c;不适用。 1. 打开 Define Setup Requirements and Actions –> Custom Actions 2. 右健 After Register Product –> Ne…

理解C#中的string类型

作者&#xff1a;未知目的 本文的目的在于揭示和DOTNET及C#相关的一些常见的和不常见的问题。在这些问题中我的第一篇文章和string数据类型有关,string数据类型是一种引用类型,但是当和其他引用类型比较的时候,很多开发人员可能并不能完全理解它的行为。 问题 对于常见的引用类…

最全总结!聊聊 Python 操作PDF的几种方法

作者 | 陈熹来源 | 早起Python前言本文主要涉及&#xff1a;os 模块综合应用glob 模块综合应用PyPDF2 模块操作基本操作PyPDF2 导入模块的代码常常是&#xff1a;from PyPDF2 import PdfFileReader, PdfFileWriter这里导入了两个方法&#xff1a;PdfFileReader 可以理解为读取器…