# retrofit_next **Repository Path**: hxhjava/retrofit_next ## Basic Information - **Project Name**: retrofit_next - **Description**: HarmonyOS Next 网络请求框架,基于@ohos.net.http库和@ohos.request,也可以支持其它http库扩展。旨在项目开发中,快速集成 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2024-10-21 - **Last Updated**: 2024-10-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # retrofit_next ## 简介 HarmonyOS Next自己的Retrofit网络请求库,默认基于@ohos.net.http库和@ohos.request,也可以支持其它http库扩展。可高度自定义,通过TypeScript构造器, 快速实现鸿蒙http网络请求。 ### [点击查看含目录的文档,查看更轻松](https://gitee.com/lowen/retrofit_next/blob/master/README.md) ## 安装教程 ``` ohpm install @lowen/retrofit_next ``` ## 全局配置 ### 初始化 ``` import { Retrofit } from '@lowen/retrofit_next' Retrofit.Builder() .setHost(host: string) // 设置全局host .setHttpFactory(factory: HttpFactory) // 设置Http请求构建工厂,默认OhosHttpFactory .addInterceptor(interceptor: Interceptor) // 添加拦截器,默认会加入LogInterceptor .setHeaders(headers: Map) // 设置Header .addHeader(key: string, value: string) // 添加Header .setConvertorFactory(factory: ConvertorFactory) // Response数据转换,直接影响每个请求返回数据层级 .setRequestTaskFactory(requestTaskFactory: RequestTaskFactory) // 请求任务管理器,默认DefaultRequestTaskFactory .setConnectTimeout(timeout: number) // 设置超时时间 .setLoadingFactory(factory: LoadingFactory) // 设置Loading状态构建工厂 .build() ``` ### 拦截器 请求拦截器,可自定义配置 ``` Retrofit.Builder() .addInterceptor(interceptor: Interceptor) // 添加拦截器,默认会加入LogInterceptor .build() ``` ### 数据转换器 全局处理Response数据,统一处理返回数据,配置方式: ``` Retrofit.Builder() .setConvertorFactory(factory: ConvertorFactory) // Response数据转换,直接影响每个请求返回数据层级 .build() ``` - 样例: ``` import { ConvertorFactory, Response } from '@lowen/retrofit' // 业务Response export interface BizResponse { code: number message?: string data?: T } export interface NetworkError extends BizError {} export interface BizError { code: number message?: string } export class BizConvertorFactory extends ConvertorFactory { public convertor(resp: Response): Promise { return new Promise((resolve, reject) => { // 接口请求成功 if (resp.isOk) { // 剥离出业务Response let bizResp = resp.result as BizResponse if (bizResp.code == 200) { // 业务处理成功,直接返回请求数据对象,这里返回数据会直接返回到请求方法的返回值,如这里是User // async get(@Loading loadingCallback: LoadingCallback): Promise { // return {} as User // } resolve(bizResp.data) } else { // 业务失败,直接抛出异常 let bizError: BizError = { code: bizResp.code, message: bizResp.message, } reject(bizError) } } else { // 接口请求异常,直接抛出异常 let bizError: NetworkError = { code: resp.code ?? 500, message: resp.message, } reject(bizError) } }) } } ``` > 注:通过ConvertorFactory配置,可以自定义接口方法的返回值类型 ## 请求状态 ### 全局配置 全局请求状态配置,配置方式 ``` Retrofit.Builder().setLoadingFactory(new HttpLoadingFactory()) ``` - 例: ``` export class HttpLoadingFactory extends LoadingFactory { start(url: string): void { LoadingDialog.showLoading() } end(url: string): void { LoadingDialog.hide() } } ``` ### BaseNoLoading 类级别装饰器,局部配置Class下所有方法不响应setLoadingFactory()全部Loading配置 ``` @BaseNoLoading export class ApiNoLoadService {} ``` ### NoLoading 方法级别装饰器,方法级别不响应setLoadingFactory()全部Loading配置 ``` @GET('/get') @NoLoading async getLoading(): Promise { return {} as User } ``` ### Loading 方法级别装饰器,当Class使用@BaseNoLoading时,当前方法级别响应setLoadingFactory()全部Loading配置 ``` @GET('/get') @NoLoading async getLoading(): Promise { return {} as User } ``` ### Loadable 参数级别装饰器,优先级高于Loading和NoLoading,动态配置是否使用全局LoadingFactory ``` @GET('/get/user') async get(@Loadable loadable: boolean): Promise> { return {} as BizResponse } ``` ### LoadState 参数级别装饰器,优先级最高,通过@LoadState和LoadStateCallback配对使用,监控请求开始和结束,不受其它Loading相关装饰器影响 ``` @GET('/get/user') async get(@LoadState loadStateCallback: LoadStateCallback): Promise> { return {} as BizResponse } ``` ## Host配置 ### 1. 全局配置 ``` Retrofit.Builder().setHost('https://xxxxx.com') // 设置全局host ``` ### 2. 类配置 优先级高于全局配置,作用于为当前类对象请求 ``` @Host('https://xxxxx.com') export class ApiService {} ``` ## Header配置 ### 1. 全局配置 优先级最低,若未配置Content-type,则默认会自动加入Header:'Content-Type', 'application/json', ``` Retrofit.Builder().setHeaders(headers: Map) // 设置Header Retrofit.Builder().addHeader(key: string, value: string) // 添加Header ``` ### 2. 类配置 优先级高于全局配置 ``` @BaseHeaders({ 'Content-type': 'application/json; charset=UTF-8' }) export class ApiService {} ``` ### 3. 方法配置 优先级高于类配置 ``` @Headers({ 'key1': 'value1', 'key2': 'value2', }) async get(): Promise> { return {} as BizResponse } ``` ### 4. 参数配置 优先级高于方法配置 #### Header ``` async get(@Header('key1') key1: string, @Header('key2') key2: string): Promise> { return {} as BizResponse } ``` #### HeaderMap HeaderMap和Map结合 ``` async get(@HeaderMap map: Map): Promise> { return {} as BizResponse } ``` ## 普通请求 支持GET,POST,OPTIONS,HEAD,PUT,DELETE,TRACE,CONNECT ### GET ``` @GET('/get/user') async get(): Promise> { return {} as BizResponse } ``` ### POST ``` @POST('/post') async post(@Body body: PostRequest): Promise> { return {} as BizResponse } ``` ## 上传下载 ### Progress 上传下载进度,参数类型必须为ProgressCallback ``` /** * @totalByteCount 当前已经完成的字节数 * @processByteCount 全部字节数 */ export type ProgressCallback = (totalByteCount: number, processByteCount: number) => void; ``` ### Upload 1. @Body,上传非文件参数,默认HttpFactory仅限key-value数据结构 2. 文件上传,上传进度由@Progress和ProgressCallback配置。 - @Config 上传配置,参数类型必须为UploadConfig ``` export class UploadConfig { /** * 扩展配置,自定义用 */ public extra?: Object constructor(extra: Object) { this.extra = extra } } ``` #### Part 1. 单位件上传,作用于方法参数 2. 参数类型必须为PartFile,否则保存 ``` /** * 上传,请求标头中的文件名. */ export class PartFile { /** * 文件名称 */ filename: string; /** * 表单项的名称 */ name: string; /** * 文件的本地存储路径 */ uri: string; /** * 文件后缀或类型 */ type: string; } ``` - 样例: ``` @Upload @POST('/upload') async upload(@Part file: PartFile, @Progress progressCallback: ProgressCallback): Promise> { return {} as BizResponse } ``` > 注:支持upload(@Part file1: PartFile, @Part file2: PartFile)多文件上传 #### PartList 1. 多文件上传,作用于方法参数 2. 参数类型必须为Array\ - 样例: ``` @Upload @POST('/upload') async upload(@PartList file: PartFile[], @Progress progressCallback: ProgressCallback): Promise> { return {} as BizResponse } ``` ### Download 文件下载,可以通过GET或POST相关配置设置下载url(鸿蒙网络库GET和POST不会生效),也可以通过@Url直接设置下载url。 - @Config 下载配置,参数类型必须为DownloadConfig ``` export class DownloadConfig { /** * 目标文件Path */ public targetPath: string /** * 扩展配置,自定义用 */ public extra?: Object constructor(targetPath: string, extra?: Object) { this.targetPath = targetPath this.extra = extra } } ``` - 样例: ``` @Download @GET('/get/user/info') async download(@Config config: DownloadConfig, @Progress progressCallback: ProgressCallback): Promise> { return {} as BizResponse } ``` ## 方法参数 ### Path 1. 在URL路径段中替换指定的参数值。 2. 使用toString()和URL编码将值转换为字符串。 3. 使用该注解定义的参数的值不可为空参数值默认使用URL编码 ``` @GET('/get/{p1}/info') async get(@Path('p1') p1: string): Promise> { return {} as BizResponse } ``` > 例:若参数p1='user',请求完整path为:/get/user/info ### Query 1. 用于添加查询参数,即请求参数(Query = Url 中 ‘?’ 后面的 key-value) 2. 参数值通过toString()转换为String并进行URL编码 ``` @GET('/get/user/info') async get(@Query('p1') p1: string, @Query('p2') p2: string): Promise> { return {} as BizResponse } ``` > 例:get('v1','v2'),Path为:/get/user/info?p1=v1&p2=v2 ### QueryMap 1. 以map的形式添加查询参数,即请求参数 2. 参数值通过toString()转换为String并进行URL编码 3. 参数类型必须为Map,否则会报错 ``` @GET('/get/user/info') async get(@QueryMap querys: Map,): Promise> { return {} as BizResponse } ``` > 例:let params:Map = new Map()
> params.set('p1','v1')
> params.set('p2','v2')
> get(params)
> > Path为:/get/user/info?p1=v1&p2=v2 > ### Url 直接传入一个请求的URL变量,设置请求url,直接替换到原有配置。 ``` @Download async download(@Url url: string, @Config config: DownloadConfig, @Progress progressCallback: ProgressCallback): Promise> { return {} as BizResponse } ``` ### FormUrlEncoded FormUrlEncoded不能用于Get请求,不要乱用 1. 用于修饰Field注解和FieldMap注解 使用该注解,表示请求正文将使用表单网址编码。字段应该声明为参数,并用@Field注释或FieldMap注释。使用FormUrlEncoded注解的请求将具”application / x-www-form-urlencoded” MIME类型。 #### Field 发送 Post请求时提交请求的表单字段,与 @FormUrlEncoded 注解配合使用 ``` @FormUrlEncoded @POST("/post") async post(@Field("time") long time): Promise> { return {} as BizResponse } @FormUrlEncoded @POST("/post") async post(@Field("name") String... names): Promise> { return {} as BizResponse } ``` #### FieldMap 表单字段,与Field、FormUrlEncoded 配合;接受 Map 类型,非String类型会调用 toString() 方法 ``` @FormUrlEncoded @POST("/post") Call> things(@FieldMap Map params); return {} as BizResponse } ``` ## 自定义扩展 ### 扩展装饰器 BaseExtra(类级别装饰器),FixedExtra(方法级别装饰器),Extra(参数级别装饰器),自定义扩展获取,RequestTask.extra, 该扩展参数可在Interceptor和自定义RequestTaskFactory,HttpFactory中使用 - 例 ``` @BaseExtra('BaseExtra') export class ApiService { @FixedExtra('FixedExtra') async getLoading(@Extra extra: string): Promise { return {} as User } } ``` 自定义http请求工厂 ``` /** * 鸿蒙原生Http构建工厂 */ export class CustomHttpFactory extends HttpFactory { /** * http网络请求 * @param task 请求任务 * @returns */ public httpRequest(task: RequestTask): Promise { let extra: ExtraObject | undefined = task.extra } } ``` 自定义拦截器 ``` export class LogInterceptor extends Interceptor { public intercept(chain: Chain): Promise { let extra: ExtraObject | undefined = chain.request.extra } } ``` ### 请求任务自定义管理 重写RequestTaskFactory,默认[DefaultRequestTaskFactory](https://gitee.com/lowen/retrofit_next/blob/master/library/src/main/ets/factory/DefaultRequestTaskFactory.ets) ### 网络请求自定义 重写HttpFactory,默认[OhosHttpFactory](https://gitee.com/lowen/retrofit_next/blob/master/library/src/main/ets/factory/OhosHttpFactory.ets)