CxHttp基于kotlin协程封装的轻量级网络请求框架

cxhttp

Coroutine Extensions Http(协程扩展Http框架)

  • 支持get、post(setBody(T,contentType,可单独指定RequestBodyConverter)、formBody、multipartBody)、delete、patch等请求

  • 支持自定义RequestBodyConverter和ResponseConverter,默认实现JacksonConverter

    interface RequestBodyConverter {
        val contentType: String
        fun <T> convert(value: T, tType: Class<out T>): ByteArray
    }
    interface ResponseConverter {
        fun <T> convert(body: Response.Body, tType: Class<T>): T
        fun <T, RESULT: CxHttpResult<T>> convertResult(body: Response.Body, resultType: Class<RESULT>): RESULT
        fun <T, RESULT: CxHttpResult<List<T>>> convertResultList(body: Response.Body, resultType: Class<RESULT>): RESULT
    }
    
  • 支持自定义请求结果类型,每个请求可以单独指定ResponseConverter

  • 支持统一请求结果CxHttpResult<T>,T为自定义类型

    /**
     * CxHttp统一请求结果基类,T为任意类型,默认实现 @see HttpResult
     * 调用者可实现自己的基类,属性名称无限制,但构造器(参数顺序及个数)必须包含与CxHttpResult一致的构造器
     * 例:data class MyHttpResult<T>(val code: Int/String,
     *                            val errorMsg: String,
     *                            val data: T?,): CxHttpResult<T>(code.toString(), errorMsg, data)
     * */
    abstract class CxHttpResult<T>(internal val cxCode: String, internal val cxMsg: String, internal val cxData: T?)
    
  • 支持HookRequest(添加公共头信息、参数等)和HookResponse、HookResult(预处理请求结果,例如token失效自动刷新并重试功能、制作假数据测试等等)功能

  • 支持自定义CxHttpCall,默认实现Okhttp3Call

    interface CxHttpCall {
        suspend fun await(request: Request): Response
    }
    
  • 支持okhttp3相关配置可直接通过Okhttp3Call配置,代码示例如下:

    val okhttp3Call = Okhttp3Call{
        callTimeout(15, TimeUnit.SECONDS)
        addInterceptor(CallServerInterceptor())
        ......
    }
    CxHttpHelper.init(call=okhttp3Call)
    

示例

添加gradle依赖

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.zhzc0x.cxhttp:cxhttp:1.2.2")
    //默认网络请求库Okhttp3Call,如果使用其它网络库可去掉
    implementation("com.squareup.okhttp3:okhttp:4.9.3")//最新版本不兼容Android4.4
    implementation("com.squareup.okhttp3:logging-interceptor:4.9.3")
    //可选JacksonConverter()
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2")
    //可选GsonConverter()
    implementation("com.google.code.gson:gson:2.10.1")
}

初始化全局配置

    val okhttp3Call = Okhttp3Call{
        callTimeout(15, TimeUnit.SECONDS)
        addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
    }    
    val jacksonConverter = JacksonConverter()
    CxHttpHelper.init(scope=MainScope(), debugLog=true, call=MyHttpCall(okhttp3Call), converter=jacksonConverter)

GET请求

    val job = CxHttp.get("https://www.baidu.com")
         //此处可指定协程,不指定默认使用CxHttpHelper.scope
        .scope(this).launch{ response ->
            if(response.body != null){
                println("resultGet1: ${response.body<String>()}")
            } else {
                // TODO: Can do some exception handling
            }   
        }
    val resultGet2 = CxHttp.get("https://www.baidu.com").await().bodyOrNull(String::class.java)
    println("resultGet2: $resultGet2")

    val resultDeferred = CxHttp.get("https://www.baidu.com").async()
    val resultGet3: String? = resultDeferred.await().bodyOrNull()
    println("resultGet3: $resultGet3")

POST请求

    CxHttp.post(TEST_URL_USER_UPDATE){
        //You can set params or body
        params(mapOf(
            "name" to "zhangzicheng",
            "age" to 32,
            "gender" to "男",
            "occupation" to "农民"))
        setBody(UserInfo("zhangzicheng", 32, "男", "农民"), UserInfo::class.java)
        //可单独设置requestBodyConverter,自定义实现RequestBodyConverter接口即可,默认使用CxHttpHelper.init()设置的全局converter
        bodyConverter = jacksonConverter
    }.launchResult<UserInfo, MyHttpResult<UserInfo>>{ resultPost1 ->
        println("resultPost1: $resultPost1")
    }
    CxHttp.post(TEST_URL_USER_PROJECTS){
        param("page", 1)
        param("pageSize", 2)
    }.launchResultList<ProjectInfo, MyHttpResult<List<ProjectInfo>>>{ resultPost2 ->
        println("resultPost2: $resultPost2")
    }

POST form、multipart

    CxHttp.post("form url"){
        formBody {
            append("name", "value")
        }
    }.await().isSuccessful
    CxHttp.post("multipart url"){
        multipartBody {
            append("name", "value")
            append("name", "filename", "filepath")
            append("name", null, File("filepath"))
        }
    }.await().isSuccessful

HookRequest

    CxHttpHelper.hookRequest { request ->
        request.header("token", tokenInfo?.accessToken ?: "")
        request.param("id", "123456")
    }

HookResponse

    CxHttpHelper.hookResponse { response ->
        if(response.code == 401){
            println("hookResponse: token失效,准备刷新并重试")
            tokenInfo = refreshToken()
            response.setReCall()//设置重新请求
        }
        response
    }

高级用法

HookResult(Hook统一请求结果CxHttpResult<*>)

    CxHttpHelper.hookResult { result: CxHttpResult<*> ->
        result as MyHttpResult
        if(result.code == 401){
            println("hookResult: token失效,准备刷新并重试")
            tokenInfo = refreshToken()
            result.setReCall()//设置重新请求
        }
        result
    }

欢迎大家点赞评论,多提Issues github.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容