掌桥专利:专业的专利平台
掌桥专利
首页

请求处理方法、装置、电子设备及计算机可读存储介质

文献发布时间:2024-04-29 00:47:01


请求处理方法、装置、电子设备及计算机可读存储介质

技术领域

本申请涉及计算机技术领域,尤其涉及一种请求处理方法、装置、电子设备及计算机可读存储介质。

背景技术

现有技术中,客户端与服务器端之间进行通信的重要底层模块中包括客户端的网络层,网络层与客户端的其他业务相关,同时具有通用性。不同的服务器端对数据信息有不同的数据要求、加密要求及验签要求等要求,同时,在客户端所有需要请求服务器端数据的地方,均需要通过访问网络层以请求服务器端数据。

然而,调用通用的逻辑函数或封装类簇函数对应的接口存在修改逻辑函数或封装类簇函数的调用方式的可能性。调用过程中,调用的数据量大,导致扩展和统计逻辑函数或封装类簇函数的接口时,需要开发人员自觉地定期维护接口,耗时耗力、复杂度高且准确性差。客户端网络层会引入不同的封装类簇,不同的封装类簇之间也存在着差异问题,导致在使用不同的封装类簇对应的封装类簇函数的困难度高。

发明内容

有鉴于此,本申请实施例提供了一种请求处理方法、装置、电子设备及计算机可读存储介质,以解决现有技术中使用不同的封装类簇对应的封装类簇函数的困难度高的问题。

本申请实施例的第一方面,提供了一种请求处理方法,包括:

监听用户请求,基于用户请求确定请求信息,请求信息包括用户请求对应的事件类型、业务类型及第一请求函数,第一请求函数为对数据结构体实现的请求流程接口执行扩展操作得到;

基于第一请求函数,通过第一请求函数调用执行用户请求对应的第二请求函数,第二请求函数为请求动作类对应的第二请求函数;

基于事件类型调用请求对象,控制请求对象调用请求实体组装函数,以通过请求实体组装函数得到请求信息对应的请求结构体,请求实体组装函数为对请求接口执行扩展操作得到;

按照请求结构体及第二请求函数请求服务器端执行用户请求。

本申请实施例的第二方面,提供了一种请求处理装置,包括:

确定模块,被配置为监听用户请求,基于用户请求确定请求信息,请求信息包括用户请求对应的事件类型、业务类型及第一请求函数,第一请求函数为对数据结构体实现的请求流程接口执行扩展操作得到;

第一处理模块,被配置为基于第一请求函数,通过第一请求函数调用执行用户请求对应的第二请求函数,第二请求函数为请求动作类对应的第二请求函数;

第二处理模块,被配置为基于事件类型调用请求对象,控制请求对象调用请求实体组装函数,以通过请求实体组装函数得到请求信息对应的请求结构体,请求实体组装函数为对请求接口执行扩展操作得到;

请求模块,被配置为按照请求结构体及第二请求函数请求服务器端执行用户请求。

本申请实施例的第三方面,提供了一种电子设备,包括存储器、处理器以及存储在存储器中并且可在处理器上运行的计算机程序,该处理器执行计算机程序时实现上述方法的步骤。

本申请实施例的第四方面,提供了一种计算机可读存储介质,该计算机可读存储介质存储有计算机程序,该计算机程序被处理器执行时实现上述方法的步骤。

本申请实施例与现有技术相比存在的有益效果是:监听用户请求,根据监听到的用户请求确定请求信息,请求信息中包括用户请求对应的事件类型、业务类型及第一请求函数,其中,第一请求函数是对数据结构体实现的请求流程接口执行扩展操作得到,能够通过请求信息所包括的事件类型、业务类型及第一请求函数避免了不同接口及不同接口变化等差异。通过第一请求函数调用执行用户请求对应的第二请求函数,即对请求流程接口执行扩展操作得到第一请求函数,通过第一请求函数调用第二请求函数,其中,第二请求函数为请求动作类中的第二请求函数,从而实现根据请求信息调用第二请求函数,达到请求服务器端处理用户请求的目的。

根据事件类型调用请求对象,控制请求对象调用请求实体组装函数,以通过请求实体组装函数得到请求信息对应的请求结构体,其中,请求实体组装函数是对请求接口执行扩展操作得到的,从而能够实现通用的网络层以处理用户请求,当网络层发生变动时不影响监听并处理用户请求的逻辑,减少差异化。

附图说明

为了更清楚地说明本申请实施例中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。

图1是本申请实施例的一种应用场景的场景示意图;

图2是本申请实施例提供的一种请求处理方法的结构图;

图3是本申请实施例提供的一种请求处理方法的流程示意图;

图4是本申请实施例提供的一种内部调用组件的调用处枚举层次图;

图5是本申请实施例提供的一种数据结构体实现请求接口的方法流程图;

图6是本申请实施例提供的另一种请求处理方法的结构图;

图7是本申请实施例提供的一种请求处理装置的示意图;

图8是本申请实施例提供的电子设备的示意图。

具体实施方式

以下描述中,为了说明而不是为了限定,提出了诸如特定系统结构、技术之类的具体细节,以便透彻理解本申请实施例。然而,本领域的技术人员应当清楚,在没有这些具体细节的其它实施例中也可以实现本申请。在其它情况中,省略对众所周知的系统、装置、电路以及方法的详细说明,以免不必要的细节妨碍本申请的描述。

下面将结合附图详细说明根据本申请实施例的一种请求处理方法和装置。

图1是本申请实施例的一种应用场景的场景示意图。该应用场景可以包括第一终端设备101、第二终端设备102和第三终端设备103、服务器104以及网络105。

第一终端设备101、第二终端设备102和第三终端设备103可以是硬件,也可以是软件。当第一终端设备101、第二终端设备102和第三终端设备103为硬件时,其可以是具有显示屏且支持与服务器104通信的各种电子设备,包括但不限于智能手机、平板电脑、膝上型便携计算机和台式计算机等;当第一终端设备101、第二终端设备102和第三终端设备103为软件时,其可以安装在如上所述的电子设备中。第一终端设备101、第二终端设备102和第三终端设备103可以实现为多个软件或软件模块,也可以实现为单个软件或软件模块,本申请实施例对此不作限制。进一步地,第一终端设备101、第二终端设备102和第三终端设备103上可以安装有各种应用,例如数据处理应用、即时通信工具、社交平台软件、搜索类应用、购物类应用等。

服务器104可以是提供各种服务的服务器,例如,对与其建立通信连接的终端设备发送的请求进行接收的后台服务器,该后台服务器可以对终端设备发送的请求进行接收和分析等处理,并生成处理结果。服务器104可以是一台服务器,也可以是由若干台服务器组成的服务器集群,或者还可以是一个云计算服务中心,本申请实施例对此不作限制。

需要说明的是,服务器104可以是硬件,也可以是软件。当服务器104为硬件时,其可以是为第一终端设备101、第二终端设备102和第三终端设备103提供各种服务的各种电子设备。当服务器104为软件时,其可以是为第一终端设备101、第二终端设备102和第三终端设备103提供各种服务的多个软件或软件模块,也可以是为第一终端设备101、第二终端设备102和第三终端设备103提供各种服务的单个软件或软件模块,本申请实施例对此不作限制。

网络105可以是采用同轴电缆、双绞线和光纤连接的有线网络,也可以是无需布线就能实现各种通信设备互联的无线网络,例如,蓝牙(Bluetooth)、近场通信(Near FieldCommunication,NFC)、红外(Infrared)等,本申请实施例对此不作限制。

需要说明的是,第一终端设备101、第二终端设备102和第三终端设备103、服务器104以及网络105的具体类型、数量和组合可以根据应用场景的实际需求进行调整,本申请实施例对此不作限制。

应用程序客户端的网络层是客户端和服务器端之间进行通信的重要底层模块,网络层和服务器端之间具体通信方式和进行通信的业务有关,但又具有通用性,通用性具体表现为:

11)不同的服务器端有不同的数据信息要求、加密要求及签名要求,其中,数据信息要求包括请求数据和返回数据,这部分是和具体通信的业务相关联的。

例如,在同一个车载应用中,负责车控通信的服务器端URL为http://xxxx/车控服务名/具体路径,对于返回数据的格式要求为:{status:数字,data:具体数据},而负责社区通信的服务器端URL为http://xxxx/社区服务名/具体路径,对于返回数据的格式要求为:{code:数字,msg:消息,data:具体数据}。可知,若在车控及社区间进行通信,两端对于数据信息的要求不一致,导致通信异常艰难。

12)外部调用组件是客户端所有需要请求服务器数据的地方,均会访问网络层,外部调用组件通过将需要访问的服务器URL、具体业务参数、具体第一请求函数等参数传递至网络层,网络层根据上述参数选择合适的逻辑通道,选择一个服务器端进行通信。

现有技术中,通常在需要调用网络请求的地方调用预先写好的通用的逻辑函数或者封装类簇,然而,使用通用的逻辑函数或封装类簇存在以下缺点:

21)在需要调用网络请求的地方,调用通用的逻辑函数或者封装类簇,调用的数据量极大,难以对逻辑函数或封装类簇进行维护和管理。例如,在当前应用程序上加入另一个后台,发生请求的步骤(包括加密和验签)、数据格式、URL组装格式可能均与现有的不一致,此时需要对逻辑函数及封装类簇进行修改,修改的同时可能会影响到外部调用组件对逻辑函数和封装类簇的调用方式,从而对调用方式也进行修改,数据量极其庞大。

22)使用通用的逻辑函数或者封装类簇不易于扩展和统计。外部调用组件对网络层的调用量是极大且频繁的,例如后台需要整理接口、清理接口时,需要客户端告知后台已调用的服务和接口,以及冗余的服务和接口等,根据逻辑函数或封装类簇进行统计的工作量较大且繁复,一般是通过人为全量搜索代码实现的,但由于外部调用部件处理请求的复杂性,人为全量搜索不一定准确,且耗时耗力。现有技术中,统计和扩展逻辑函数或封装类簇的方式为把所有调用的URL写在配置文件或外部调用组件中,需要开发人员自觉且定期的维护URL,非常不稳定。

23)传统的客户端的网络层实现非常繁复,引入封装类簇以解决代码及实现逻辑的差异性问题时,对代码阅读理解和使用均是一种挑战。

综上,需要一种简单的、易于管理的网络层结构及外部调用组件,以实现屏蔽复杂的加密验签逻辑、服务器接口变化及不同服务器端的差异,同时便于统计客户端接口调用请求,易于客户端扩展或删除服务器端调用接口。

图2是本申请实施例提供的一种请求处理方法的结构图,如图2所示,本申请提供的实施例在处理用户请求时,涉及到请求处理方法的结构中包括五种接口,分别为请求接口、请求流程接口、数据结构体、事件类型对应的事件接口及外部调用组件对应的接口。

其中,将事件接口所在的组件称为内部调用组件,调用组件包括内部调用组件及外部调用组件,网络层中包括请求接口、请求流程接口、数据结构体及事件接口,外部调用组件用于执行网络层以外的处理操作。用户请求对应的请求信息由外部调用组件传递至网络层对应的各接口以实现根据请求信息请求服务器端执行用户请求。

当接收到服务器端根据请求信息执行处理操作返回的返回结果,对返回结果进行解析或传递返回结果,通过外部调用组件将返回结果呈现给用户。

搭建上述请求处理方法的结构所需的编程语言具有以下特性:

扩展(Extension):扩展是一种可以向现有类、结构体、枚举或协议类型添加新功能的方式,而不需要重新定义这些类型本身,并允许将一些功能添加到不相关的类型上,或为某个第三方库添加特定的功能;

接口(Protocol):接口是一种定义规范的方式,规定了一个类或结构体需要实现哪些方法和属性,接口是一种类型,可以被当做函数的参数或者作为变量使用,从而使得开发人员能够更加灵活地设计和组织具体实现逻辑;

泛型(Generic):泛型是一种允许在定义类型时使用占位符的方式,将占位符称作泛型参数,从而可以创建适用于任何类型的通用函数或类型,泛型使得代码更加灵活,并且可以减少代码的重复。在使用泛型时,能够将占位符替换为任何实现过程中需要的类型。

存在多种满足上述特性的编程语言以搭建上述请求处理方法的结构,实现请求处理方法,本申请实施例中,以Swift语言为例,进行示例性的说明。

本申请实施例涉及的请求信息类型为HTTP请求,处理HTTP请求的步骤包括三步:客户端请求服务器端、收到回复及解析数据,实现上述步骤需要一个类来管理步骤流程,这个类包括请求动作类及数据解析类。

其中,请求动作类负责管理更底层的网络请求类、函数,将请求信息对应的网络请求类及函数等有效组合起来。例如:iOS系统提供的网络请求类和函数,也可以是第三方封装过的类和函数,如Alamofire。本申请实施例会用Alamofire实现进行说明,进一步的,本申请实施例涉及的实现也可以用iOS系统函数实现。

用户请求的类型包括普通请求、上传请求及下载请求,数据解析类负责解析服务器端返回的普通用户请求的返回结果,因为对于资源的上传或下载,可以当做对文件的处理,即通过请求流程接口中转后,将上传资源或下载资源的实现直接交给外层处理。

对于第一请求函数从服务器端回调的数据:由于不同服务器端传回的基础数据格式可能不一致,故需要由数据解析类统一进行处理,屏蔽差异后,再进行合理组装,返回给外层。

进一步的,因为具体的服务器端接口返回的业务数据格式上存在差异,例如:订单的业务数据格式包括:订单名称、订单对应的商品、商品编号、商品名、订单价格等,而用户对应的业务数据包括:用户编号、用户名称、用户生日、用户性别等。

上述数据在网络层并不需要关注,故可以通过Swift语言提供的泛型来表示上述数据,本申请实施例可以通过执行请求组件将上述业务数据传出到外层,在外层进行处理。

图3是本申请实施例提供的一种请求处理方法的流程示意图。如图3所示,该请求处理方法包括以下步骤:

S301,监听用户请求,基于用户请求确定请求信息,请求信息包括用户请求对应的事件类型、业务类型及第一请求函数,第一请求函数为对数据结构体实现的请求流程接口执行扩展操作得到;

S302,通过第一请求函数调用执行用户请求对应的第二请求函数,第二请求函数为请求动作类对应的第二请求函数;

S303,基于事件类型调用请求对象,控制请求对象调用请求实体组装函数,以通过请求实体组装函数得到请求信息对应的请求结构体,请求实体组装函数为对请求接口执行扩展操作得到;

S304,按照请求结构体及第二请求函数请求服务器端执行用户请求。

图3的请求处理方法可以由图1的任一包括图2请求处理方法的结构的终端设备执行,以按照请求结构体及第二请求函数请求图1的任一服务器端执行用户请求。

外部调用组件监听用户发送的用户请求,当监听到用户请求,对用户请求进行处理,以得到用户请求对应的请求信息,请求信息中包括用户请求对应的事件类型、业务类型及第一请求函数,第一请求函数是对请求流程接口执行扩展操作得到的,请求流程接口用于实现数据结构体。

通过第一请求函数调用执行用户请求对应的第二请求函数,第二请求函数是请求动作类对应的第二请求函数。请求动作类是一个独立的类,是真正向服务器端发起请求的地方,对请求流程接口执行扩展操作得到的第一请求函数需要请求动作类中的成员函数,可以理解为请求流程接口依赖于请求动作类。

其中,成员函数包括第二请求函数、上传函数及下载函数,在向服务器端发起请求时均使用第二请求函数,上传函数及下载函数用于处理接收到服务器端执行用户请求后返回的返回结果,即可以将用户请的类型求分为上传请求、下载请求及普通请求,网络层在请求服务器端执行用户请求时,对用户请求的类型不做区分,均使用第二请求函数请求服务器端执行用户请求,在接收到服务器端返回的返回结果时,按照用户请求的类型处理返回结果,具体为:当用户请求为普通请求时,通过普通请求对应的回调函数处理返回结果,当用户请求为上传请求时,通过上传请求对应的回调函数处理返回结果,当用户请求为下载请求时,通过下载函数对应的回调函数处理返回结果。

业务类型表示<业务实体类>,<业务实体类>是Swift语言提供的指定泛型具体类型的一种方式,例如,在接收到用户请求时,确定用户请求为商品实体类,则该用户请求对应的<业务实体类>为商品实体类,网络层根据商品实体类的逻辑处理该用户请求。

其中,业务类型可以写作泛型D,泛型D为泛型T的一个成员属性,在本申请提供的实施例中,由数据结构体实现了泛型T,请求服务器端执行用户请求之后,服务器端返回用户请求的执行结果,执行结果通过回调函数发送至数据解析类,数据解析类返回泛型T的一个实例。泛型T中还包括执行状态码及执行状态信息等其他成员属性,外部调用组件按需使用泛型T中的所有成员属性。泛型D与泛型T之间的关系为:泛型T是由数据结构体自身实现的泛型,而泛型D则是泛型T根据外部调用组件对应的业务数据指定的成员属性。

本申请一示例性实施例中,以Swift语言构建数据结构体为例,对泛型D和泛型T之间的关系进行示例性的说明:

构建一个数据结构体声明,也就是实现了请求流程接口的结构体,命名为JKJSONData,遵循HandyJSON协议。其中D为本申请实施例中涉及的泛型D,同样也遵循HandyJSON协议。

这个数据结构体可以用于封装任意遵循HandyJSON协议的类型的JSON数据。通过指定不同的泛型D,可以创建不同类型的JKJSONData实例,并且可以使用HandyJSON库中的方法对它们进行JSON序列化和反序列化操作。

struct JKJSONData: HandyJSON where D: HandyJSON {

private var status = false

var code = ""

var message = ""

var success = false

var rows: [D]?

var data: D?

var total = 0

var mediaCount = 0

var traceId = ""};

其中,private var status = false表示服务器端执行用户请求返回的执行状态消息,var code = ""表示服务器端执行用户请求返回的执行状态码,var message = ""表示服务器端执行用户请求返回的消息,var success = false表示服务器端执行用户请求返回的用户请求执行状态,执行状态包括成功或失败,var rows: [D]?表示业务数据列表,var data: D?表示业务数据,var total = 0表示业务数据列表的总数,var mediaCount =0表示某些接口的其他总数,var traceId = ""表示错误追踪ID。

JKJSONData它指定泛型T为自己的方式如下:

extension JKJSONData: Requestable {

typealias T = Self

}。

请求流程接口的定义如下:(其中,associatedtype指定了泛型T)

typealias BlockT= (T)->Void

protocol Requestable {

associatedtype T: HandyJSON

typealias ResultHandler = (Response.Result)->Void

typealias FileHandle = (Response.FileResult)->Void

static func request(_ request: RequestAPI, result: ResultHandler?)

static func upload(images: [Image], privateKeyFlag: Bool, _shouldWatermark: Bool?, result: ResultHandler?, progress:ImageProgressHandle?)

static func download(downloadUrl:String, fileSaveUrl: URL, result:BlockT?)

};

其中,上述代码中涉及的result均表示回调函数,对应普通请求、上传请求及下载请求分别为普通回调函数、上传回调函数及下载回调函数。static func request()为普通的请求函数,用于处理普通请求,参数request表示请求结构体。static func upload()为上传请求函数,用于处理上传函数,上述代码中为处理上传图片的函数,参数images表示图片数组,参数privateKeyFlag表示私钥,shouldWatermark表示是否为上传的图片添加水印。static func download()为下载请求的函数,用于处理下载请求,将文件下载到指定的URL,downloadUrl表示下载地址,fileSaveUrl表示用户发送的下载文件保存路径。

进一步的,泛型T是由请求流程接口定义的associatedtype,用于表示业务数据的具体类(也就是具体数据实体类),其中,使用了associatedtype关键字的接口会称为一个泛型接口,T相当于是个类型占位符,而实现请求流程接口的具体类必须用具体的类,故本申请实施例通过请求流程接口处理用户请求时,使用数据结构体。

事件类型表示子枚举case值,即通过事件类型调用请求对象,请求对象的执行逻辑为:对请求接口执行扩展操作得到的请求实体组装函数,将请求信息传入入参,以得到请求信息对应的请求结构体。

请求动作类按照请求结构体及第二请求函数请求服务器端执行用户请求。

其中,外部调用组件监听到用户请求,将请求信息写入如下函数,以请求网络层的各接口:数据结构体<业务实体类>.第一请求函数(调用处枚举.子枚举.枚举case值){数据结构体 回调函数具体逻辑},其中,各参数分别意为:

31)指定数据结构体的泛型D的类型为指定的业务实体类,例如商品实体类;

32)对数据结构体调用第一请求函数,因为数据结构体实现了请求流程接口,即本身存在第一请求函数;

33)第一请求函数的入参要求是实现了请求接口的某实体和回调函数,在具体实现时,某实体为上述事件类型,回调函数为:在回调函数执行前,可以在数据解析类实例和回调函数具体逻辑的结构之间进行适应性调整,并在回调函数中,加入其余开发所需逻辑;

34)调用处枚举.子枚举.枚举case值:表示请求信息中的事件类型,是本申请实施例提供的一种写法,即调用处枚举的子枚举对应case值,也就是具体请求处理的接口值;

35)数据结构体 回调函数具体逻辑:因为回调函数的参数是泛型T,在本申请实施例中,实现了泛型T的就是数据解析类,返回泛型T的一个实例。这个参数用于处理返回结果时使用,在请求服务器执行用户请求时不使用该逻辑。

上述可知,通过本申请实施例提供的架构实施请求处理方法,能够通过各接口之间的调用处理用户请求,避免了不同服务器端的底层数据的不同,同时避免了网络层各接口的数据变动带给外部调用组件带来的感知。

在一些实施例中,请求动作类用于根据第二请求函数及请求结构体实现用户请求,第一请求函数还用于调用请求动作类的第二请求函数,

通过第一请求函数调用执行用户请求对应的第二请求函数,包括:

控制第一请求函数通过请求流程接口在第一请求函数中调用执行用户请求的请求动作类所对应的第二请求函数。

对请求流程接口执行扩展操作,即对请求流程接口声明并定义第一请求函数及第一请求函数的实际代码,从而实现了请求流程接口的所有子类都可以拥有并调用第一请求函数,在第一请求函数里面调用请求动作类的第二请求函数,从而第一请求函数访问到了请求动作类实例,数据结构体实现了请求流程接口,其中,请求动作类可以设计为一个单例,以实现网络请求之间的排他性,请求动作类也可以根据业务需求,设计为一个普通的类,以实现网络请求的并发操作。

第一请求函数来源于对请求流程接口执行扩展操作得到的,故通过数据结构体能够调用请求流程接口的第一请求函数,而第二请求函数是请求动作类对应的第二请求函数,请求流程接口依赖于请求动作类,故第一请求函数通过请求流程接口在第一请求函数中调用第二请求函数,其中,第二请求函数的入参包括请求结构体,请求结构体来源如后续实施例中描述。

根据本申请实施例提供的技术方案,外部调用组件监听到用户请求,并确定用户请求对应的请求信息,能够根据请求信息中的第一请求函数通过请求流程接口在第一请求函数中调用执行用户请求的第二请求函数,从而请求服务器端执行用户请求。

在一些实施例中,请求信息还包括请求数据及关联值,请求数据包括请求头字段、请求方式、请求域名、请求类型、请求路径及请求参数,关联值包括用户请求对应的业务数据,事件类型继承于请求接口,事件类型还包括关联值,每一事件类型对应有一个或多个关联值;

所有事件类型保存在调用处枚举,调用处枚举继承于请求接口;

或,

事件类型按照预设保存规则保存在对应的子枚举,所有子枚举保存在调用处枚举,调用处枚举继承于请求接口。

事件类型表示case值,每一事件类型对应存在一个或多个关联值,例如:事件类型为商品时,需要关联值x与关联值y,事件类型为用户时,需要关联值a与关联值b,事件类型为订单时,需要关联值h、关联值j与关联值d,可以表示为:

->case商品(关联值x,关联值y);

->case用户(关联值a,关联值b);

->case订单(关联值h,关联值j,关联值d)。

在一种实施方式中,将所有事件类型保存在调用处枚举,即将调用处枚举作为保存有所有事件类型的集合,读取调用处枚举的内容数据时,能够直接读取到所有事件类型及事件类型对应的关联值。

在另一种实施方式中,将事件类型按照预设保存规则保存在对应的子枚举中,所有的子枚举保存在调用处枚举,即将多个子枚举case值封装至同一个子枚举中,多个子枚举通过对父枚举(即调用处枚举)进行扩展的形式包括在同一个父枚举中,每一子枚举均需要实现请求接口,每个服务器端接口对应一个子枚举的case值,即枚举值,例如:enum商城枚举{case 商品列表接口;case 单个商品详情接口;case 商品规格接口;case 加入购物车接口;case 购物车商品列表接口;……},其中enum表示调用处枚举的子枚举。可以表示为:

调用处枚举 ->enum1

->enum2

->enum3

每一个enum(子枚举)中包括一个或多个case值:

enum1 ->case商品列表接口(关联值c,关联值e);

->case单个商品详情接口(关联值f);

->case商品规格接口(关联值k,关联值l,关联值m);

->case加入购物车接口(关联值n,关联值o);

->case购物车商品列表接口(关联值g,关联值p);……。

每一子枚举包括对应的成员变量及成员方法,即请求对象及请求实体组装函数,指定对应的子枚举以得到对应的请求结构体,请求对象(即计算属性)的执行步骤为:

41)确定请求信息对应的子枚举,对子枚举通过switch的方式遍历子枚举自身的所有case,其中,switch的方式为Swift语言所提供的功能;

42)对于每个case,调用子枚举自身从扩展的请求接口中获得的请求实体组装函数,对请求实体组装函数传入关联值(即入参),从而请求实体组装函数能够按照请求对象生成请求信息对应的请求结构体,即在内部调用组件中,该函数的返回值为请求封装组件根据请求返回的请求结构体。

其中,入参包括服务器端要求的请求方法、服务器端的域名、服务器端的类型、服务器端提供服务的路径及请求参数,对于不同的服务器端接口,输入参数是不同的,故输入参数的格式、类型及要求是由定义各子枚举时确认的,而具体的参数值是根据外部调用组件传入所确定。

图4是本申请实施例提供的一种内部调用组件的调用处枚举层次图,如图4所示,将调用处枚举作为父枚举,父枚举包括多个子枚举,可以为车控对应的子枚举、商城对应的子枚举、用户对应的子枚举、社区对应的子枚举及权益对应的子枚举,在商城对应的子枚举中,包括case商品列表接口、case单个商品详情接口及case购物车商品列表接口。

根据本申请实施例提供的技术方案,利用Swift语言的扩展、接口及泛型数据的特点,提供了一种简单的网络层及外部调用组件进行请求处理的实现,通过少量的类实例和简单的类关系实现了通用的网络层,能够处理各类用户请求对应的请求信息,从而避免外部调用组件对网络层变动的感知。同时,在网络层的内部调用组件处可选的设置了父枚举及子枚举,能够更加清晰的划分业务的同时易于扩展和统计网络层与服务器端的接口,提升维护的便捷程度及灵活性。

在一些实施例中,基于事件类型调用请求对象,控制请求对象调用请求实体组装函数,包括:

基于事件类型重写请求对象,在重写请求对象的同时,将关联值转换为请求参数;

在已重写的请求对象中,调用请求接口对应的请求实体组装函数,并将请求数据作为入参传递至请求实体组装函数。

对请求接口执行扩展操作得到请求实体组装函数,根据请求信息的事件类型重写请求对象,同时,在重写请求对象时,将关联值转换为请求参数。

在已重写的请求对象中,调用请求接口对应的请求实体组装函数,并将请求数据作为入参传递至请求实体组装函数,以得到用户请求对应的请求结构体,即上述实施例中涉及的第二请求函数的入参。其中,每一事件类型代表一种业务,不同的事件类型代表一个case值,请求数据包括请求头字段、请求方式、请求域名、请求类型、请求路径及请求参数,此处请求参数为在重写请求对象的同时转换关联值得到的请求参数,即请求结构体的入参包括用户请求对应的请求头字段、请求方式、请求域名、请求类型、请求路径及请求参数。

本申请一示例性实施例中,以Swift语言,在已重写的请求对象中,调用请求接口对应的实体组装函数,并将请求数据作为入参传递至请求实体组装函数为例,进行示例性的说明:

A)定义请求接口RequestAPI:

protocol RequestAPI {var request: JKRequest {get}};

其中,var request: JKRequest表示请求对象。

B)对请求接口执行扩展操作,并在已扩展的请求接口中定义请求实体组装函数:

extension RequestAPI {

func apiRequest(method: JKRequest.Method = .post,

taskType: JKRequest.TaskType = .plain,

host: String = baseUrl,

service: HostService = .app,

path: String = "",

needsToken: Bool = true,

params: JKRequest.Params? = [:]) ->JKRequest {

var header: JKRequest.Headers = [Header.ContentTypeKey: Header.ContentType.json.rawValue,

Header.DeviceKey: UIDevice.modelName,

Header.AppVersionKey: UIDevice.appVersion,

Header.SysVersionKey: UIDevice.current.systemVersion,

Header.MobileModelKey: "IOS",

Header.AuthorizationKey: AccountManager.shared.token ?? "",

Header.LanguageKey: GlobalManager.shared.language.identifier,

Header.TokenKey: AccountManager.shared.token ?? "",

Header.AppTypeKey: "S1",

Header.MsgIdKey:"(Date().timeIntervalSince1970* 1000)_(Lets.uuidString)".md5]

let req = JKRequest.init(header, host, service, taskType, path: path,method: method, params: params)

return req}};

其中,func apiRequest()为请求实体组装函数,该请求实体组装函数接收所有涉及的入参,参数params表示业务参数,例如订单对应的订单ID及该订单对应的用户ID等;

var header用于组装多个服务器端共有的请求头字段,DeviceKey为设备密钥,AppVersionKey为当前应用程序的版本号,SysVersionKey为当前系统版本号,MobileModelKey为手机虚拟钥匙,AuthorizationKey为授权密钥,LanguageKey为语言类型,TokenKey为令牌密钥,AppTypeKey为应用程序类型密钥,MsgIdKey为消息查询密钥;

let req用于构造一个“请求结构体”对象并返回,JKRequest参数为请求结构体;请求实体组装函数通过return req返回得到的请求结构体的一个实例。

C)定义调用处枚举API,以实现请求接口RequestAPI:

enum API : RequestAPI {}。

D)在调用处枚举API的扩展里定义子枚举UserInfo,子枚举中包括的case代表一些具体的业务场景,每一个case均对应有一个或多个关联值,即业务数据:

extension API {

enum UserInfo {

case getUserInfo(_ userId: String?)

case modifyUserInfo(params: [String: Any])

case getInfoTotal(userId: String)

case changePhone(params: [String: Any])}

};

其中,UserInfo为个人信息的子枚举,getUserInfo表示获取个人信息,modifyUserInfo表示修改个人信息,getInfoTotal表示获取关注、粉丝、积分、收藏的相关数据,changePhone表示更改手机号。

E)使子枚举UserInfo实现请求接口RequestAPI,并且重写请求接口RequestAPI所定义的请求对象request:

extension API.UserInfo: RequestAPI {

var request: JKRequest {

switch self {

case .getUserInfo(let userId):

var path = "public/users/detail"

if let uId = userId {

path = "public/users/(uId)/detail"}

return apiRequest(method: .get, taskType: .formUrlEncoded, path:path, params: nil)

case .modifyUserInfo(let params):

return apiRequest(method: .post, taskType: .jsonParams, path: "public/user", params: params)

case .getInfoTotal(let userId):

return apiRequest(method: .get, taskType: .formUrlEncoded, path: "public/user/get-info-total", params: ["userUuid": userId])

case .changePhone(let params):

return apiRequest(method: .post, taskType: .jsonParams, path: "public/users/mobile", params: params)}}};

其中,var request: JKRequest为重写请求对象request的过程,switch self{}表示先遍历所有case值,对每一case值,调用请求实体组装函数apiRequest,构造出请求结构体对应的实例并返回,其中,getUserInfo表示获取个人信息,var path表示默认查询当前用户信息,如果传入uId代表查询其他用户的信息,modifyUserInfo表示修改个人信息,getInfoTotal表示获取关注、粉丝、积分、收藏的相关数据,changePhone表示更改手机号。

由于在Swift语言中,在扩展中定义的函数代码会插入每一个实现这个接口的具体类中,故对请求接口中执行扩展操作,得到名为“请求实体组装函数”的扩展函数,所以每一个实现了请求接口的具体类都拥有对应的请求实体组装函数,它们的类实例可以随时调用这个请求实体组装函数。

本申请一示例性实施例中,请求实体组装函数的输入参数包括:

51)服务器端所要求的请求方式:枚举类型,请求方式在业务开发中通常使用HTTP协议的post或get方式;

52)服务器端的域名:字符串类型,其中,域名一般和服务器端绑定,不同的服务器端后台拥有不同的域名,不同的实现环境的服务器端也有不同的域名;

53)服务器端的类型:枚举类型,上述涉及区分不同服务器端后台,例如商品后端部署在服务器A上,则商品后端对应一个枚举值case1,社区服务器端后台部署在服务器B上,则社区服务器端对应另一个枚举值case2;

54)服务器端提供的服务路径:字符串类型,每个服务器端能够提供多种服务,例如商品服务器端提供的服务包括订单查询、订单提交及订单退款等服务,每个服务的服务路径是不同的;

55)请求参数:即每个服务要求的具体请求参数,可以是字典类型,例如订单查询服务的要求为传入订单号,订单提交的要求为传入用户购买的商品号、对应的个数及用户信息等,每个服务的参数是不同的,一般通过键值对的形式进行存储,在Swift语言中,键值对又称为字典。

请求实体组装函数的返回值为请求信息对应的请求结构体,该函数有两个步骤,分别是组装多个服务器端共有的HTTP头字段(即请求头字段);通过请求结构体的构造函数生成一个请求结构体并返回。

其中,第二个步骤具体为:将HTTP头字段作为构造函数的第一个入参,并将上述请求实体组装函数的参数作为构造函数请求头字段之外的入参。

本申请一示例性实施例中,多个服务端共有的HTTP头字段可以设置为:“设备”:“iphonex”、“系统”:“iOS14”、“用户的token”:“fjadskfj23998424ajkfa”等,其中,用户的token为该用户对应的一串在一段时间内有效的唯一标识,本申请实施例中是一串字符串。

其中,结构体是Swift语言中的一种类型,和类、枚举并称为Swift语言三大类型,请求结构体对应的构造函数的输入参数包括HTTP头字段、请求方式、请求域名、请求类型、请求路径及请求参数,上述入参在形成请求结构体后,作为请求结构体所包括的成员变量。

其中,请求对象为一个计算属性,计算属性可以理解为函数,存在对应的实现步骤,同时返回一个请求结构体。计算属性是Swift语言中的一种属性,它和其他语言中的成员属性不同,计算属性的作用类似于一个方法,返回值就是计算属性所声明的类型对应的实例。

其中,请求结构体的主要功能包括生成签名及由上述构造函数生成实际的HTTP请求对象。

生成签名的过程包括:调用签名函数,获取请求信息对应的签名及时间戳,签名函数的实现步骤为:获取验签的访问key、获取验签的加密key及验签。

获取验签的访问key的入参(即传入参数)为服务器端枚举类型,返回值为验签的访问key;

获取验签的访问key的实现步骤包括读取配置文件,根据不同的服务器端,得到对应验签的访问key,验签的访问key由服务器端提供。

其中,验签为服务器端为了保证客户端传入的数据没有被篡改,会制定一套规则,让客户端将自己所传参数、URL等数据进行某种计算,得到一个唯一的字符串,随着其他数据一起上传给服务器。服务器端也会用同样的规则将客户端数据进行计算,然后对比自己生成的唯一的字符串和客户端发送的唯一的字符串是否一致,从而确定数据的完整性和防篡改性。

获取验签的加密key的入参包括服务器端枚举类型,返回值为验签的加密key;

获取验签的加密key的实现步骤包括读取配置文件,根据不同的服务器端对应的端值,得到对应验签的加密key,验签的加密key是由服务器端提供的。

其中,验签的访问key和加密key均可以看做生成签名过程中的不变常量。

在获取到验签的访问key及验签的加密key之后,可执行验签:

验签的入参包括请求类型(即服务器端枚举类型)、请求方式、基础域名、服务路径及请求参数,返回值为签名(一个字符串);

验签的实现步骤为根据预定义的验签生成规则,确定当前请求信息对应的签名,即对应的字符串。

本申请一示例性实施例中,以一种验签生成规则为例,进行示例性说明:

61)根据服务器端枚举类型及服务路径组装出实际的请求路径,例如:商品服务器端/获取商品积分:mallproductservice/mall/getIntegral;

62)判断请求方式,当请求方式是get请求:

取当前时间的时间戳,将时间戳数字按从小到大进行排序,得到对应的时间字符串;

调用函数以获取验签的加密key,得到加密key;

将61)中的请求路径和请求参数按照HTTP的方式进行组装(由于HTTP规定get请求方式,其参数就是拼接在路径后面的),得到get方式对应的的请求路径,如:mallproductservice/mall/getIntegral?mallid=3&status=notorder;

即,将时间字符串、加密key及get方式对应的请求路径进行组合,对组合得到的字符串进行求散列值,求散列值所得的字符串作为签名所对应的字符串,其中,求散列值可以通过iOS系统提供的SHA散列算法CC_SHA256函数得到。

63)判断请求方法,如果是post请求:

取当前时间的时间戳,得到对应的时间字符串;

调用函数:获取验签的加密key,得到加密key;

把时间字符串加入请求参数,将所有请求参数(字典)转成json字符串,并用&符号连接,得到参数字符串;

即,将时间字符串、加密key、参数字符串及请求路径四者进行组合,对组合所得的字符串再进行求散列值,求散列值所得的字符串作为签名所对应的字符串,其中,求散列值可以通过iOS系统提供的SHA散列算法CC_SHA256函数得到。

其中,上述涉及到的所有验签的实现步骤均可换成加密的实现,或者在上述实现步骤的基础上添加加密功能与验签并行。

由构造函数生成实际的HTTP请求对象,即由构造函数生成URLRequest类实例的实现步骤如下:

其中,URLRequest类实例是iOS系统提供的HTTP请求类。

确定构造函数的输入参数,输入参数包括请求头字段、请求方式、请求域名、请求类型、请求路径及请求参数。

构造函数的实现步骤为:

71)调用验签函数,生成签名字符串;

72)根据验签的输入参数所包括的请求类型,即服务器端枚举,对公用的请求头字段进一步填充,例如商品服务器端需要传入用户的身份信息,车控服务器端需要传入车辆的身份信息等;

同时,将签名字符串和验签过程中生成的时间字符串也加入请求头字段;

同时,调用获取验签的访问key,把它加入到请求头字段,从而形成完整的请求头字段(即HTTP请求头);

73)读取配置文件,根据请求方式及当前应用程序的环境状态,组装不同的基础域名,例如商品服务器端的基础域名在测试环境下是:https://mall-test.com/,在线上环境是:https://mall-uat.com/;

74)把基础域名、请求类型、请求路径及请求参数组成请求URL;

例如:上述涉及GET方式对应的请求URL需要带上请求参数,则创建URLRequest类实例时,这是iOS系统提供的请求类。该类实例的构造函数需要:请求URL、请求方法及请求参数。

75)如果是post方式,将请求参数转成字符串,再转成二进制流后赋值给URLRequest类实例的httpBody属性;

76)将URLRequest类实例赋值给请求结构体的成员属性,生成用户请求对应的请求结构体。

根据本申请实施例提供的技术方案,能够通过事件类型重写请求对象,并在已重写的请求对象中调用实体组装函数,同时将请求数据作为入参的参数传递至请求实体组装函数,以得到请求信息对应的请求结构体,能够按照请求结构体及第二请求函数请求服务器端执行用户请求,从而实现对用户请求的处理,通过验签的实现步骤能够实现客户端和服务器端之间安全的消息传递,保证了防篡改性,同时避免了数据格式的不同带来的影响,能够更灵活的应对不同的请求信息。

外部调用组件根据请求信息确定对数据结构体实现的请求流程接口执行扩展操作得到的第一请求函数及业务类型,业务数据可通过泛型D进行表示,不同的业务数据对应不同的格式,通过泛型D进行转换,以统一业务数据的格式,例如,有些业务数据为字典格式,将其转换为数据实体D,有些业务数据为列表格式,将其转换为包装数据实体D的一个数组,转换的过程在执行相应函数的过程中完成。

从二进制数据转换为数据实体的过程有多种实现方式,可以是利用iOS提供的json转换工具进行自研,也可以是利用第三方工具进行转换,将执行转换的过程称为数据结构体构造函数。

在一些实施例中,用户请求包括普通请求、上传请求及下载请求,按照请求结构体及第二请求函数请求服务器端执行用户请求之后,还包括:

接收服务器端基于请求结构体及第二请求函数执行处理操作并返回的返回结果;

当用户请求为普通请求,将返回结果传入数据解析类进行解析,得到解析结果,解析结果包括用户请求对应的业务数据及通用数据,作为数据结构体的成员变量;

将数据结构体传递至外部调用组件中普通请求对应的回调函数,作为普通请求对应的回调函数的参数。

当用户请求为普通请求,外部调用组件中对应的普通请求函数的通用写法为:数据结构体<业务实体类>.第一请求函数(调用处枚举.子枚举.枚举case值){数据结构体 回调函数具体逻辑};

当用户请求为上传请求,外部调用组件中对应的上传函数的通用写法为:数据结构体<业务实体类>.第一请求函数(资源数组,调用处枚举.子枚举.枚举case值){数据结构体 回调函数具体逻辑};

当用户请求为下载请求,外部调用组件中对应的下载函数的通用写法为:数据结构体<业务实体类>.第一请求函数(下载URL,下载的文件路径){数据结构体 回调函数具体逻辑}。

其中,普通请求函数、上传函数及下载函数中的第一请求函数用于根据用户信息请求服务器端执行用户请求,并调用数据解析类实例或静态函数,接收服务器端返回的返回结果并进行处理。“{数据结构体 回调函数具体逻辑}”是回调函数的写法,回调函数由“{}”组成,数据结构体是回调函数的入参,回调函数的具体逻辑是函数体,具体是通过静态函数负责处理的。

图5是本申请实施例提供的一种数据结构体实现请求接口的方法流程图,如图5所示,数据结构体实际为能够实现请求流程接口的结构体,拥有请求流程接口扩展的三个成员函数,即第一请求函数、上传函数及下载函数,通过该数据结构体,将泛型T指定为数据结构体的类型,通过请求接口实现数据结构体,并自动拥有上述三个扩展函数。

上述数据结构体中还包括成员变量,成员变量部分能够提供给外部调用组件,以使外部调用组件直接访问成员变量,用来表示数据解析类解析服务器端执行普通用户请求返回的返回结果。其中,成员变量中包括执行状态码及执行状态消息,执行状态码及执行状态消息用于表示请求接口的执行状态,例如,设置执行成功时,执行状态码显示为0,执行状态信息显示为“成功”,设置发生错误时,执行状态码显示为111,执行状态信息显示为“登录信息错误”。

接述上例,在数据结构体的构造函数中,将负责屏蔽不同服务器端类型的不同数据结构组成统一的数据结构,也就是内部调用组件的数据结构体本身,能够提供给外部调用组件进行调用。例如,服务器端A的执行状态码名称为status,服务器端B的执行状态码称为code,各服务器端的执行状态码输入至构造函数,构造函数判断其服务器端类型,将A的status及B的code统一赋值给自己的成员变量中的执行状态码及执行状态信息,并且业务数据通过构造函数转换为泛型D。

即,当请求类型为普通请求,请求流程接口将返回结果传入数据解析类进行解析,得到解析结果,解析结果中包括用户请求对应的业务数据及通用数据,将业务数据通过数据结构体传递至外部调用组件中普通请求对应的回调函数,数据结构体(即泛型T的具体实现者)作为普通请求对应的回调函数的参数;

当请求类型为上传请求或下载请求,请求流程接口将泛型D通过对应的回调函数传递至外部调用组件中上传请求或下载请求对应的回调函数,作为上传请求或下载请求对应的回调函数的参数。

综上可知,请求流程接口用于请求服务器端执行用户请求,也用于接收服务器端执行用户请求的返回结果,请求流程接口的实现逻辑如下:

对请求流程接口执行扩展操作,从而得到普通请求函数、上传函数及下载函数,根据请求信息确定请求接口调用的函数,在实现了请求接口对应的所有具体类均能够调用上述函数,也可以被外部调用组件直接调用。

按照上述普通请求函数的通用写法实现普通请求对应的普通请求函数的方法为:

入参:实现了请求接口的某实体(上述实施例中根据用户请求生成的请求结构体);回调函数:返回结果经过数据解析类的一层通用处理后,作为回调函数的参数返回给外部调用组件。

函数步骤:调用请求动作类的第二请求函数,在数据解析类中解析处理第二请求函数得到的网络数据。

按照上述上传函数的通用写法实现上传请求对应的上传函数的方法为:

入参:资源数组(包括在请求数据中);

实现了请求接口的某实体(上述实施例中根据用户请求生成的请求结构体);

回调函数,将返回结果作为回调函数的参数,通过回调函数传递至外部调用组件;

函数步骤:调用请求动作类的第二请求函数。

按照上述下载函数的通用写法实现下载函数的方法为:

入参:下载请求对应的URL的字符串(包括在请求数据中);下载到的文件路径对应的字符串(包括在请求数据中);回调函数,将返回结果作为回调函数的参数,通过回调函数传递至外部调用组件;

函数步骤:调用请求动作类的第二请求函数。

请求动作类执行实际的HTTP请求动作,包括发起请求、上传资源及下载资源,资源可以是图片、视频或文件等类型的资源,其中,可以将请求动作类的实例定义为一个单例,以实现网络请求之间的排他性,也可以根据实际业务需求,将请求动作类的实例定义为一个普通的类,以实现网络请求对应的并发操作。

本申请提供的实施例中,以将动作请求类的实例定义为一个单例,包括成员变量为Alamofire工具提供的Session类实例为例,进行示例性的说明。

请求动作类所包括的成员函数的实现方法为:

当用户请求的类型为普通请求,通过普通请求函数请求服务器端执行用户请求:

其中,普通请求函数表示普通的执行HTTP请求功能,是客户端中大部分数据的交流方式。

入参:实现了请求接口的某实体(上述实施例中根据用户请求生成的请求结构体);回调函数;

普通请求函数实现步骤:

调用系统或三方函数,传入用户请求对应的请求结构体,进行实际的请求。

本申请一示例性实施例中,以使用Alamofire工具为例,具体为:调用Session类实例的函数:func request(_ convertible: URLRequestConvertible, interceptor:RequestInterceptor? = nil) ->DataRequest,其参数传入请求结构体的成员属性:URLRequest类实例,得到返回值DataRequest类对象,对这个对象调用函数:func response(queue: DispatchQueue = .main, completionHandler: @escaping (AFDataResponse) ->Void) ->Self,在其参数回调函数中,调用输入参数的回调处理块,即通过第一请求函数调用数据解析类的相关函数进行后继数据解析处理。

当用户请求的类型为上传请求,通过上传函数请求服务器端执行用户请求:

入参:资源数组(包括在请求数据中);实现了请求接口的某实体(上述实施例中根据用户请求生成的请求结构体);回调函数;

上传函数的实现步骤:

调用系统或三方函数,传入请求结构体,进行实际的请求。

本申请一示例性实施例中,以使用Alamofire工具为例,将资源数组转成二进制数据;调用Session类实例的函数:func upload()->UploadRequest;

上传函数所需要的传入参数包括:资源二进制数据;

请求URL:即请求结构体的成员变量URLRequest类实例的属性URL;

HTTP请求方式:即请求结构体的成员变量URLRequest类实例的属性方法method;

HTTP头字段:即请求结构体的成员变量URLRequest类实例的属性头字段headers。可通过上述步骤组装一个三方请求实例。

对上述函数的返回值,也就是UploadRequest类实例,调用函数:funcuploadProgress(queue:DispatchQueue = .main, closure: @escapingProgressHandler) ->Self,可以根据该函数得到进度条,在目标显示屏幕可利用进度条绘制进度;

对其返回值,也就是UploadRequest类对象,对返回值(UploadRequest类对象)调用函数:

func response(queue: DispatchQueue = .main, completionHandler: @escaping (AFDataResponse) ->Void) ->Self实现,上述函数为实际的上传函数,在其参数回调函数中,调用输入参数的回调处理块,即通过第一请求函数调用数据解析类的相关函数进行后继数据解析处理。

当用户请求的类型为下载请求,通过下载函数请求服务器端执行用户请求:

入参:下载的URL对应的字符串(包括在请求数据中);下载到的文件路径对应的字符串(包括在请求数据中);回调函数;

下载函数的实现步骤:

本申请一示例性实施例中,以使用Alamofire工具为例,调用Session类实例的函数:

unc download ( _convertible : URLConvertible , method:HTTPMethod =.get,parameters:Parameters?=nil,encoding:ParameterEncoding=URLEncoding.default,headers:HTTPHeaders?=nil,interceptor:RequestInterceptor?=nil,requestModifier:RequestModifier?=nil,to destination : DownloadRequest.Destination? = nil) ->DownloadRequest,下载函数对应的参数中包括默认参数,默认参数可以不进行传递,而默认参数以外,需要传递的参数为下载URL、下载到的文件路径及下载完成后的回调。在一些实施例中,也可以设置为传递默认参数。

接述上例,对其返回值,即下载请求DownloadRequest类对象,调用函数:

func responseData ( queue : DispatchQueue = .main , dataPreprocessor:DataPreprocessor=DataResponseSerializer.defaultDataPreprocessor,emptyResponseCodes : Set= DataResponseSerializer .defaultEmptyResponseCodes , emptyRequestMethods : Set=DataResponseSerializer. defaultEmptyRequestMethods,completionHandler:@escaping(AFDownloadResponse) ->Void) ->Self,在该函数的completionHandler中,取出二进制数据,作为参数传入回调函数中。其中,completionHandler用于返回服务器端处理用户请求的完成情况。

上述函数的实现步骤中涉及通过第一请求函数调用数据解析类的相关函数进行后继数据解析处理,在数据解析类中,返回结果由静态函数进行处理,并且,数据解析类也可以去除“类”的包装,用全局静态函数代替,然而加“类”的优点在于能够起到命名空间的作用,更便于相关人员理解。

数据解析类对应的实现方法为:

入参:回调函数,即上述实施例请求流程接口中第一请求函数对应的回调函数;

返回值:解析回调函数;

其中,返回值对应的解析回调函数与入参的回调函数不同,解析回调函数是对输入参数回调函数对应的数据进行了一层解析,将基础格式解析好,并把对应字段放入了一个基础格式实体类中。上述实施例涉及业务数据,例如用户信息、订单信息等,将业务数据存放在基础格式实体类的泛型D对应的位置,将基础格式实体类实例放在解析回调函数中,通过解析回调函数向外层传去。

数据解析类对应的静态函数的实现步骤:

本申请一示例性实施例中,以使用Alamofire工具为例,Alamofire返回的回调函数的参数就是一个Result枚举类型,通过(AFDataResponse) ->Void实现。其中,Result枚举是Swift语言提供的一种特殊的枚举,它是一个泛型,包括回调成功状态和回调失败状态,每一种枚举值都可以携带一个额外的数据,即关联值。

接述上例,由于枚举包括回调成功状态和回调失败状态,在执行请求组件将枚举对应的参数传递至数据解析类中,也是一种枚举,称为传递枚举,传递枚举包括以下步骤:

81)判断枚举值,当枚举值是回调失败状态,直接返回对应的回调函数;

82)当枚举值是回调成功状态,将上述回调的Data取出,Data是个二进制数据,利用iOS提供的json转换工具将二进制数据转成对应的数据实体(泛型T),其中,利用iOS提供的转换工具可以是调用JSONSerialization类的jsonObject(with:options)函数,这个转换过程可以是自研,也可以使用便利的三方工具如HandyJSON;

83)分析转换得到的数据结构,对不同服务器端(服务器端的类型:枚举类型),解析出对应的字段,可以归纳为:

执行状态码:可能服务器端A的执行状态码为status,服务器端B的执行状态码为code,最终解析为执行状态码;

执行状态消息:可能服务器端A的执行状态码为msg,服务器端B的执行状态码为message,最终解析为执行状态消息;

84)根据执行状态码或执行状态消息,进行特殊逻辑处理,例如:用户登录发生冲突,即用户在设备A上登录,而后在设备B上登录,则设备A的接口请求返回数据的执行状态消息是:发生冲突,此时根据业务需求可能要通知用户,通知方式包括弹框提示、退出登录等;

例如:执行状态码是404,表征可能是服务器端口已经下架,也可能是URL组装错误;

例如:在json解析过程中发生错误,表征服务器数据格式有误,根据业务需求弹框提示,可直接使用执行状态消息进行提示;

85)将执行状态码和执行状态消息中的一个或多个进行封装,直接返回给对应的回调函数,其中,执行状态码和执行状态消息的存在互不影响,可以同时存在,也可以根据业务需要存在一个;

86)不存在执行状态码或执行状态消息,则直接将数据实体(泛型T)封装为参数,直接返回给对应的回调函数。

根据本申请实施例提供的技术方案,通过动作请求类及数据解析类的设置能够最大限度的减少网络层处理的数据,加快处理速度,同时在管理网络层的接口及函数时能够减少工作量,对每一函数都存在命名,将网络层分为了结构清晰的四个组件以处理请求数据,增加了请求信息的处理灵活度。

图6是本申请实施例提供的另一种请求处理方法的结构图,上述实施例涉及的方法可按照图6所示结构图执行请求处理方法。

在一些实施例中,对于每个增加的大类业务功能模块,在调用处枚举中增加一个扩展,扩展中声明对应的子枚举,子枚举用增加的功能模块业务命名,以便于进行区分。例如,增加商场模块,则在调用处枚举中增加一个扩展,扩展中声明该子枚举为“商城枚举”。通过子枚举扩展枚举调用处与现有技术相比,若将所有服务器端接口都定义在父枚举的case中,就无法使用扩展这个灵活的功能,每次新增服务器接口,就要直接改动父枚举的定义代码,容易出错,同时无法区分具体的大业务,故本申请实施例增加了一层子枚举,能够使得业务划分更加清晰,更利于扩展。

在一些实施例中,统计调用处枚举所包含的所有子功能组件对应的case,能够统计网络层中存在网络请求的数量,实现方法为控制子功能组件实现iOS系统提供的CaseIterable接口,从而使得子功能组件拥有了一个名称为allCases的计算属性,allCases是一个数组,里面有全部的case值,即是本申请实施例中所有的接口之和。故,对“调用处枚举”的子功能组件调用allCases属性,对得到的数组访问其计算属性,就得到了该子枚举(子功能模块,如订单、商城、用户等)下的接口个数。汇总所有子功能组件的接口个数,就是该应用程序的总接口个数,实现对网络请求的统计不出错、无遗漏、便于维护的目的。

应理解,上述实施例中各步骤的序号的大小并不意味着执行顺序的先后,各过程的执行顺序应以其功能和内在逻辑确定,而不应对本申请实施例的实施过程构成任何限定。

上述所有可选技术方案,可以采用任意结合形成本申请的可选实施例,在此不再一一赘述。

下述为本申请装置实施例,可以用于执行本申请方法实施例。对于本申请装置实施例中未披露的细节,请参照本申请方法实施例。

图7是本申请实施例提供的一种请求处理装置的示意图。如图7所示,该请求处理装置包括:确定模块701,第一处理模块702,第二处理模块703,请求模块704。其中:

确定模块701,被配置为监听用户请求,基于用户请求确定请求信息,请求信息包括用户请求对应的事件类型、业务类型及第一请求函数,第一请求函数为对数据结构体实现的请求流程接口执行扩展操作得到;

第一处理模块702,被配置为通过第一请求函数调用执行用户请求对应的第二请求函数,第二请求函数为请求动作类对应的第二请求函数;

第二处理模块703,被配置为基于事件类型调用请求对象,控制请求对象调用请求实体组装函数,以通过请求实体组装函数得到请求信息对应的请求结构体,请求实体组装函数为对请求接口执行扩展操作得到;

请求模块704,被配置为按照请求结构体及第二请求函数请求服务器端执行用户请求。

在一些实施例中,请求动作类用于根据第二请求函数及请求结构体实现用户请求,第一请求函数还用于调用请求动作类的第二请求函数;

第一处理模块702,被配置为通过第一请求函数调用执行用户请求对应的第二请求函数,用于:

控制第一请求函数通过请求流程接口在第一请求函数中调用执行用户请求的请求动作类所对应的第二请求函数。

在一些实施例中,请求信息还包括请求数据及关联值,请求数据包括请求头字段、请求方式、请求域名、请求类型、请求路径及请求参数,事件类型还包括关联值,每一事件类型对应有一个或多个关联值;

所有事件类型保存在调用处枚举,调用处枚举继承于请求接口;

或,

事件类型按照预设保存规则保存在对应的子枚举,所有子枚举保存在调用处枚举,调用处枚举继承于请求接口。

在一些实施例中,第二处理模块703,被配置为基于事件类型调用请求对象,控制请求对象调用请求实体组装函数,用于:

基于事件类型重写请求对象,在重写请求对象的同时,将关联值转换为请求参数;

在已重写的请求对象中,调用请求接口对应的请求实体组装函数,并将请求数据作为入参的参数传递至请求实体组装函数。

在一些实施例中,第一处理模块702,被配置为通过请求实体组装函数得到请求信息对应的请求结构体,用于:

通过请求接口对应的请求实体组装函数得到请求信息对应的请求结构体,请求结构体的参数包括请求数据对应的请求头字段、请求方式、请求域名、请求类型、请求路径及请求参数。

在一些实施例中,调用组件包括内部调用组件及外部调用组件,内部调用组件用于执行网络层的处理操作,外部调用组件用于执行网络层以外的处理操作;

确定模块701,被配置为监听用户请求,基于用户请求确定请求信息,用于:

通过外部调用组件监听用户请求,基于用户请求确定请求信息。

在一些实施例中,用户请求包括普通请求、上传请求及下载请求,请求模块704,被配置为按照请求结构体及第二请求函数请求服务器端执行用户请求之后,还用于:

接收服务器端基于请求结构体及第二请求函数执行处理操作并返回的返回结果;

当用户请求为普通请求,将返回结果传入数据解析类进行解析,得到解析结果,解析结果包括用户请求对应的业务数据及通用数据,作为数据结构体的成员变量;

将数据结构体传递至外部调用组件中普通请求对应的回调函数,作为普通请求对应的回调函数的参数。

在一些实施例中,请求模块704,被配置为接收服务器端基于请求结构体及第二请求函数执行处理操作并返回的返回结果,还用于:

当用户请求为上传请求或下载请求,将返回结果通过对应的回调函数传递至外部调用组件中上传请求或下载请求对应的回调函数,作为上传请求或下载请求对应的回调函数的参数。

图8是本申请实施例提供的电子设备8的示意图。如图8所示,该实施例的电子设备8包括:处理器801、存储器802以及存储在该存储器802中并且可在处理器801上运行的计算机程序803。处理器801执行计算机程序803时实现上述各个方法实施例中的步骤。或者,处理器801执行计算机程序803时实现上述各装置实施例中各模块/单元的功能。

电子设备8可以是桌上型计算机、笔记本、掌上电脑及云端服务器等电子设备。电子设备8可以包括但不仅限于处理器801和存储器802。本领域技术人员可以理解,图8仅仅是电子设备8的示例,并不构成对电子设备8的限定,可以包括比图示更多或更少的部件,或者不同的部件。

处理器801可以是中央处理单元(Central Processing Unit,CPU),也可以是其它通用处理器、数字信号处理器(Digital Signal Processor,DSP)、专用集成电路(Application Specific Integrated Circuit,ASIC)、现场可编程门阵列(Field-Programmable Gate Array,FPGA)或者其它可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等。

存储器802可以是电子设备8的内部存储单元,例如,电子设备8的硬盘或内存。存储器802也可以是电子设备8的外部存储设备,例如,电子设备8上配备的插接式硬盘,智能存储卡(Smart Media Card,SMC),安全数字(Secure Digital,SD)卡,闪存卡(Flash Card)等。存储器802还可以既包括电子设备8的内部存储单元也包括外部存储设备。存储器802用于存储计算机程序以及电子设备所需的其它程序和数据。

所属领域的技术人员可以清楚地了解到,为了描述的方便和简洁,仅以上述各功能单元、模块的划分进行举例说明,实际应用中,可以根据需要而将上述功能分配由不同的功能单元、模块完成,即将装置的内部结构划分成不同的功能单元或模块,以完成以上描述的全部或者部分功能。实施例中的各功能单元、模块可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中,上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。

集成的模块/单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个可读存储介质(例如计算机可读存储介质)中。基于这样的理解,本申请实现上述实施例方法中的全部或部分流程,也可以通过计算机程序来指令相关的硬件来完成,计算机程序可以存储在计算机可读存储介质中,该计算机程序在被处理器执行时,可以实现上述各个方法实施例的步骤。计算机程序可以包括计算机程序代码,计算机程序代码可以为源代码形式、对象代码形式、可执行文件或某些中间形式等。计算机可读存储介质可以包括:能够携带计算机程序代码的任何实体或装置、记录介质、U盘、移动硬盘、磁碟、光盘、计算机存储器、只读存储器(Read-Only Memory,ROM)、随机存取存储器(Random AccessMemory,RAM)、电载波信号、电信信号以及软件分发介质等。

以上实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述实施例对本申请进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的精神和范围,均应包含在本申请的保护范围之内。

相关技术
技术分类

06120116594803