okhttp添加公共参数

在项目开发中很多时候后台都会给一些全局的公共入参,比如携带手机信息或者时间戳等字段。而我们在使用okhttp时,就需要我们单独就行二次封装处理了,对于请求全局参数,每次请求都要去写一次,那是肯定不行的。

所以就要我们自己处理。

okhttp一个强大的功能拦截器,该功能采用责任链模式,不清楚的自行百度。我采用的就是这种方案。

需要用到的知识点HttpUrl,FormBody

直接用代码解说

复制代码
import android.util.Log
import okhttp3.FormBody
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response

private const val TAG = "RequestInterceptor"

/**
 * 自定义的拦截器
 */
class RequestInterceptor : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        // 旧的请求体
        val oldRequest = chain.request()
        var newFormbodyData: FormBody? = null
        var newRequest: Request? = null
        if ("POST" == oldRequest.method) {
            // 公共参数,所有请求必须携带的,我们重新new一个请求体FormBody
            // 这个请求体只包含我们共有的请求参数
            val builder = FormBody.Builder()
            builder.addEncoded("brand", "Xiaomi")
            builder.addEncoded("model", "MIX+2")
            val formBody = builder.build()
            // 获取我们旧的请求体
            val requestBody = oldRequest.body
            // 创建我们最终的请求体
            val newFormBody = FormBody.Builder()
            // 将共有的请求参数放入我们最终的请求体中
            for (i in 0 until formBody.size) {
                newFormBody.addEncoded(formBody.encodedName(i), formBody.encodedValue(i))
            }

            // 如果配合retrofit使用,需要注意一点,在发送的post请求如果没有自己独有的字段
            // 一定要对requestBody判断是不是formBody
            requestBody?.let {
                // 通过判断之前旧的请求体是否包含有请求参数
                // 如果有的话就添加进最终请求体
                if (it.contentLength() > 0) {
                    val formBody1 = it as FormBody
                    for (i in 0 until formBody1.size) {
                        newFormBody.addEncoded(formBody1.encodedName(i), formBody1.encodedValue(i))
                    }
                }

            }
            //  拿到我们最终的请求体
            newFormbodyData = newFormBody.build()
            // 重新构建一个requsest 将请求体放入进去
            newRequest = oldRequest.newBuilder().post(newFormbodyData!!).build()

        } else if ("GET" == oldRequest.method) {
            // 如果是get请求,我们创建一个新的HttpUrl
            // 用来储存我们的scheme,host,path
            // 这段代码相当于最原始的get请求配置的信息
            //   val httpurl = HttpUrl.Builder()
            //            .scheme("https")
            //            .host("www.hxeduonline.com")
            //            .addPathSegments("mobileapi2")
            //            .addPathSegments("index.php")
            //            .addQueryParameter("act", "xxx")
            //            .addQueryParameter("op", "xxxx")

            val publicParameter = HttpUrl.Builder()
            val httpUrl = oldRequest.url
            val pathSegments = httpUrl.pathSegments
            publicParameter.scheme(httpUrl.scheme)
            publicParameter.host(httpUrl.host)
            // 将path路径赋值给最新的HttpUrl
            pathSegments.forEach {
                publicParameter.addEncodedPathSegments(it)
                Log.d(TAG, "intercept: $it")
            }
            // 设置共有的参数
            publicParameter.addEncodedQueryParameter("brand", "Xiaomi")
            publicParameter.addEncodedQueryParameter("model", "MIX+2")

            // 将接口自带的参数放入到最终的httpUrl
            for (i in 0 until httpUrl.querySize) {
                publicParameter.addQueryParameter(
                    httpUrl.queryParameterName(i),
                    httpUrl.queryParameterValue(i)
                )
            }
            // 构建httpUrl
            val build = publicParameter.build()
            // 构建一个新的request
            newRequest = oldRequest.newBuilder().url(build).get().build()

        }
        // 全局配置参数就完成了,思路基本就是这样,扩展可以根据自己需求,比如加密都可以在这里处理
        return chain.proceed(newRequest!!)
    }
}
相关推荐
sweetying2 小时前
30了,人生按部就班
android·程序员
用户2018792831673 小时前
Binder驱动缓冲区的工作机制答疑
android
真夜3 小时前
关于rngh手势与Slider组件手势与事件冲突解决问题记录
android·javascript·app
用户2018792831673 小时前
浅析Binder通信的三种调用方式
android
用户093 小时前
深入了解 Android 16KB内存页面
android·kotlin
火车叼位4 小时前
Android Studio与命令行Gradle表现不一致问题分析
android
前行的小黑炭6 小时前
【Android】 Context使用不当,存在内存泄漏,语言不生效等等
android·kotlin·app
前行的小黑炭7 小时前
【Android】CoordinatorLayout详解;实现一个交互动画的效果(上滑隐藏,下滑出现);附例子
android·kotlin·app
用户20187928316719 小时前
Android黑夜白天模式切换原理分析
android
芦半山19 小时前
「幽灵调用」背后的真相:一个隐藏多年的Android原生Bug
android