retrofit2网络请求的kotlin版本封装

从最早网络请求使用httpclient开始,到后面只用okhttp, 到使用retrofit2 ,(听闻retrofit2有kotlin版本,但是我去官网看似乎仍然是java 的)

虽然网络框架还是基于java的。但是多数项目都开始使用kotlin编写。所以对自己之前的封装的网络框架也使用kotlin重构一下吧。

其实还有一些变化,在测试版本的as中 ,权限请求的方法也过时了,结构变得更灵活,所以以后会把那个再重新封装一下。

常规的app用的最多的感觉就是访问网络和权限请求了。好了就这些,这次的封装还耐心的写了注解,并且补全了复合数据的提交。哈哈希望看了这篇的能有点收获吧

有些业务逻辑相关的部分简写了,可以根据实际去扩展。下面是主要代码,其实有部分还没有完善,等再有时间会整理一下。发布到github的仓库。

class CommonHttp {
    companion object {
        lateinit var mBaseUrl: String
        lateinit var retrofit: Retrofit
        lateinit var client:OkHttpClient
        lateinit var callBack:(back:HttpMessage)->Unit;
    }

    /**
     * 不使用拦截器的构造方法
     */
    constructor(baseUrl:String,function:(back:HttpMessage)->Unit){
        callBack=function
        mBaseUrl=baseUrl
        if(retrofit==null) {
            var httpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()
            var dispatcher = Dispatcher()
            dispatcher.maxRequests = 128
            dispatcher.maxRequestsPerHost = 32
            httpBuilder.dispatcher(dispatcher)
            httpBuilder.connectionPool(ConnectionPool(32, 20, TimeUnit.MILLISECONDS))
            client =
                httpBuilder.readTimeout(3, TimeUnit
                    .MINUTES).connectTimeout(3, TimeUnit.MINUTES)
                    .writeTimeout(
                        3,
                        TimeUnit.MINUTES
                    ).build()
            retrofit = Retrofit.Builder().baseUrl(baseUrl).client(client).build();
        }
    }

    /**
     * 带拦截器的构造方法。多个域名的情况可以考虑使用
     */
    constructor(baseUrl:String,interceptor: Interceptor,function:(back:HttpMessage)->Unit){
        callBack=function
        mBaseUrl=baseUrl
        if(retrofit==null) {
            var httpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()
            var dispatcher = Dispatcher()
            dispatcher.maxRequests = 128
            dispatcher.maxRequestsPerHost = 32
            httpBuilder.dispatcher(dispatcher)
            httpBuilder.connectionPool(ConnectionPool(32, 20, TimeUnit.MILLISECONDS))
            client =
                httpBuilder.readTimeout(3, TimeUnit.MINUTES).connectTimeout(3, TimeUnit.MINUTES)
                    .writeTimeout(
                        3,
                        TimeUnit.MINUTES
                    ).addInterceptor( if (interceptor==null) BaseUrlInterceptor() else interceptor).build()
                retrofit = Retrofit.Builder().baseUrl(baseUrl).client(client).build();

        }
    }
    fun doRequest(vararg objects:Any){
        var call:Call<ResponseBody>? = null
        var cookies:HashMap<String,String> = HashMap()
        when(objects.size){
            1->{
                var url=objects[0] as String
                call= retrofit.create(CommonHttpService::class.java).get(url)
            }
            2->{
                var url=objects[0] as String
                var params=objects[1] as HashMap<String,String>

                /**
                 * json 形式
                 */
                var jsonBody:RequestBody= RequestBody.create(MediaType.parse("application/json;charset=utf-8"),
                    JSON.toJSONString(params))
                /**
                 * form 表单格式
                 */
                var formBodyBuilder=FormBody.Builder()
                for(param in params){
                    formBodyBuilder.add(param.key,param.value)
                }
                var formBody=formBodyBuilder.build()
                call= retrofit.create(CommonHttpService::class.java).post(url,params,jsonBody)//json 或表单形式提交

            }
            3->{
                var url=objects[0] as String
                var params=objects[1] as HashMap<String,String>
                var files=objects[2] as HashMap<String, File>
                /**
                 * 复合表单格式,适合同时提交参数与文件
                 */
                var  builer=MultipartBody.Builder()
                for(param in params){
                    builer.addFormDataPart(param.key,param.value)
                }
                for(file in files){
                    var requestBody=RequestBody.create(MediaType.parse("application/octet-stream"),file.value)
                    builer.addFormDataPart(file.key,file.value.name,requestBody)
                }
                var multipartBody=builer.build()
                call= retrofit.create(CommonHttpService::class.java).postFile(url,multipartBody.parts())
//                call= retrofit.create(CommonHttpService::class.java).post(url,cookies,multipartBody)//不同的请求格式,两种都可以,看服务器接收格式
            }

        }
        call?.enqueue(object: retrofit2.Callback<ResponseBody> {
            override fun onResponse(
                call: Call<ResponseBody>,
                response: retrofit2.Response<ResponseBody>,
            ) {
                Log.e("http","请求成功")
               if(response!=null) {
                   var message = Message()
                   message.obj = response
                   message.what=0
                   handler.sendMessage(message)
               }else
               {
                   handler.sendEmptyMessage(-1)
               }

            }
            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                Log.e("http","请求异常")
                handler.sendEmptyMessage(-1)
            }

        })
    }

    /**
     * httpmsg type 0成功 1失败 -1异常。指代服务器返回结果,-1访问失败 使用
     *  code 指代服务器业务逻辑返回码
     *  result 返回的数据
     */
    var handler= object:Handler(Looper.getMainLooper()){
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            var httpmsg=HttpMessage()
            var response=msg.obj as retrofit2.Response<ResponseBody>
            var result=response.body().toString()
            var resultFormat=getResultFormat(result)
            when(msg.what){
                -1->{
                    httpmsg.type=-1
                    callBack(httpmsg)
                }
                0->{
                    when(response.code()){
                        200-> {

                            httpmsg.code = resultFormat.code
                            /**
                             * 业务逻辑层面判断成功与失败
                             */
                            if(resultFormat.code==1000) {
                                httpmsg.type=0
                                httpmsg.msg = resultFormat.msg
                                httpmsg.result = result
                            }else{
                                httpmsg.type=1
                                httpmsg.msg = resultFormat.msg
                                httpmsg.result = result
                            }
                        }
                        500,400,404->{
                            httpmsg.type=-1
                            httpmsg.code=response.code()
                        }
                    }
                    callBack(httpmsg)
                }
            }
        }
    }
    fun getResultFormat(json:String):ResultFormat{
        return JSON.parse(json) as ResultFormat
    }

    /**
     * 默认拦截器。在baseurl改变时进行重定向
     */
    class BaseUrlInterceptor:Interceptor{
        open override fun intercept(chain: Interceptor.Chain): Response {
            var request:Request=chain.request()
            var oldHttpUrl:HttpUrl=request.url()
            var builder:Request.Builder=request.newBuilder()
            var newHttpUrl:HttpUrl= HttpUrl.parse(mBaseUrl)!!
            var httpUrl=oldHttpUrl.newBuilder().scheme(newHttpUrl.scheme()).
            host(newHttpUrl.host()).port(newHttpUrl.port()).build()
            return  chain.proceed(builder.url(httpUrl).build())
        }
    }
}


data class ResultFormat(var msg:String,var code:Int)
data class HttpMessage(var type:Int=-1,var code:Int=-1,var msg:String="",var result:String="")
interface CommonHttpService {
    @HTTP(method="POST",path="{url}",hasBody=true)
    @Headers("ContentType:application/json;charset=UTF-8")
    fun post(@Path(value="url",encoded = true) url:String?,@HeaderMap() cookies:HashMap<String,String>
    ,@Body body:RequestBody): Call<ResponseBody>

    @HTTP(method = "GET", hasBody = false)
    operator fun get(@Url url: String?): Call<ResponseBody>

    @HTTP(method = "GET", hasBody = false)
    operator fun get(
        @Url url: String?,
        @HeaderMap tokens: HashMap<String?, String?>?
    ): Call<ResponseBody>

    @Multipart
    @HTTP(method = "POST", path = "{url}", hasBody = true)
    fun postFile(
        @Path(value = "url", encoded = true) url: String?,
        @Part parts: List<MultipartBody.Part?>?
    ): Call<ResponseBody>
    
    @Multipart
    @HTTP(method = "POST", path = "{url}", hasBody = true)
    fun postFile(
        @Path(value = "url", encoded = true) url: String?,
        @Header("Cookie") token: String?,
        @Part parts: List<MultipartBody.Part?>?
    ): Call<ResponseBody>
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值