Retrofit2网络请求拦截器

统一日志上报拦截器:

  • 区分Get、POST、Form
  • 重新发起请求
  • 仅供参考(复杂、不建议)
package com.test.checkpoint.net

import android.net.Uri
import com.test.checkpoint.MainApplication
import com.test.checkpoint.constants.toJson
import com.test.checkpoint.utils.ACache
import com.test.checkpoint.utils.LINK_IP
import com.test.checkpoint.utils.LINK_PORT
import okhttp3.*
import okio.Buffer
import java.io.UnsupportedEncodingException
import java.nio.charset.Charset

class ServiceBusInterceptor : Interceptor {

    lateinit var keyUrl: String

    companion object {
        const val REGEX = "[https]+://([0-9]{1,3}.){3}[0-9]{1,3}(:)?[0-9]{0,5}"
        const val TAG = "ServiceBusInterceptor"
        const val APP_KEY = "7E64C7A55DC221DC2D5BFF3BD61D554B"
        const val SERVICE_KEY_GET = "7f0d95150ee33cec8254b9a9c25f94a7"
        const val SERVICE_KEY = "a79b666b57c13820b9c658f863d5321a"
        const val SERVICE_KEY_1 = "8e5ace94b6903317bba90d5b9990141e"
    }

    override fun intercept(chain: Interceptor.Chain): Response {
        val builder = chain.request().newBuilder()
        builder.addHeader("appKey", APP_KEY)
        keyUrl = "http://$LINK_IP:$LINK_PORT/platform/redirect"
        builder.url(keyUrl)
        when (chain.request().method()) {
            "GET" -> {
                builder.addHeader("serviceKey", SERVICE_KEY_GET)
                return chain.proceed(newGetRequest(chain.request(), builder))
            }
            "POST" -> {
                builder.addHeader("serviceKey", SERVICE_KEY)
                return chain.proceed(newJsonRequest(chain.request(), builder))
            }
        }
        return chain.proceed(builder.build())
    }

    //For Get
    private fun newGetRequest(old: Request, builder: Request.Builder): Request {
        val url = old.url()
        return builder.addHeader("ContentType", "application/json; charset=UTF-8").post(
            RequestBody.create(
                MediaType.parse("application/json; charset=UTF-8"),
                ServiceBusRequest(
                    serviceSuffix(urlRegex(url.toString())),
                    mapOf(
                        "jwt-token" to ACache.get(MainApplication.getContext())
                            .getAsString("jwt_token")
                    )
                ).toJson
            )
        ).build()
    }

    //region application/json
    private fun newJsonRequest(old: Request, builder: Request.Builder): Request {
        val url = old.url()
        val body = old.body()
        body?.let {
            val contentType = body.contentType().toString()
            android.util.Log.e(TAG, "contentType: $contentType")
            when {
                contentType.contains("x-www-form-urlencoded") -> {
                    return builder.addHeader("ContentType", "application/json; charset=UTF-8")
                        .post(
                            RequestBody.create(
                                MediaType.parse("application/json; charset=UTF-8"),
                                bodyToJson(body as FormBody, url.toString())
                            )
                        ).build()
                }
                contentType.contains("json") -> {
                    return builder.addHeader("ContentType", "application/json; charset=UTF-8")
                        .post(
                            RequestBody.create(
                                MediaType.parse("application/json; charset=UTF-8"),
                                bodyToString(body)
                            )
                        ).build()
                }
                else -> return builder.build()
            }
        }
        return builder.build()
    }
    //endregion

    //region application/x-www-form-urlencoded
    private fun newFormRequest(old: Request, builder: Request.Builder): Request {
        val url = old.url()
        val body = old.body()
        body?.let {
            builder.addHeader("ContentType", "x-www-form-urlencoded; charset=UTF-8")
            val formBodyBuilder = FormBody.Builder().apply {
                addEncoded("serviceSuffix", serviceSuffix(urlRegex(url.toString())))
                addEncoded("params", paramsToJson(body as FormBody).toJson)
            }
            builder.post(formBodyBuilder.build())
        }
        return builder.build()
    }
    //endregion

    //region params to json map
    private fun paramsToJson(body: FormBody): Map<String, String> {
        val map = mutableMapOf<String, String>()
        val size = body.size()
        for (i in 0 until size) {
            map[body.name(i)] = body.value(i)
        }
        return map
    }
    //endregion

    //region body to json
    private fun bodyToJson(body: FormBody, url: String): String {
        val tokenMap =
            mapOf("jwt-token" to ACache.get(MainApplication.getContext()).getAsString("jwt_token"))
        return ServiceBusRequest(
            serviceSuffix(urlRegex(url)),
            tokenMap,
            paramsToJson(body)
        ).toJson.replace("\\", "")
    }
    //endregion

    //region body to string
    private fun bodyToString(body: RequestBody): String {
        val buffer = Buffer()
        body.writeTo(buffer)
        return buffer.readString(Charset.defaultCharset())
    }
    //endregion

    //region serviceSuffix
    private fun serviceSuffix(url: String): String {
        var newUrl: String = url.substring(keyUrl.length)
        val tag = "/kits-jcz-server"
        if (newUrl.contains(tag)) {
            newUrl = newUrl.replace(tag, "")
        }
        return newUrl
    }
    //endregion

    private fun urlRegex(url: String) = url.replace(REGEX.toRegex(), keyUrl)

    private fun paramsToJson4Get(url: String): Map<String, String> {
        val map = mutableMapOf<String, String>()
        try {
            val uri: Uri = Uri.parse(url)
            for (paramName in uri.queryParameterNames) {
                val paramValue = uri.getQueryParameter(paramName)
                map[paramName] = java.net.URLDecoder.decode(paramValue, "UTF-8")
                com.test.util.LegoLog.d("${paramName}:${paramValue}")
            }
        } catch (e: UnsupportedEncodingException) {
            e.printStackTrace()
        }
        return map
    }
}

data class ServiceBusRequest(
    var serviceSuffix: String = "",
    var serviceHeader: Map<String, String> = mapOf(),
    var params: Map<String, String> = mapOf()
)

工具类:

val Any.toJson: String
    get() = Gson().toJson(this)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 你可以使用OkHttp的Interceptor来拦截参数。在使用Retrofit时,可以通过自定义OkHttpClient并添加Interceptor来实现。以下是一个示例: ``` OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request requestWithNewParameter = originalRequest.newBuilder() .addHeader("Your-Header-Name", "Your-Header-Value") .build(); return chain.proceed(requestWithNewParameter); } }) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build(); YourApiService apiService = retrofit.create(YourApiService.class); ``` 在上面的示例中,我们添加了一个Interceptor来拦截每个请求并添加一个自定义的Header。你可以根据需要修改拦截器的实现来拦截并修改请求参数。 ### 回答2: 在Android开发中,Retrofit是一个非常流行的网络请求库。它提供了拦截器(Interceptor)的功能,可以对网络请求的参数进行拦截和修改。 拦截器是一个接口,可以在请求之前或者响应之后对请求进行处理。在Retrofit中,可以通过实现Interceptor接口来自定义拦截器。 通过拦截器,我们可以对请求进行一些通用的处理,比如对请求头进行添加、修改、删除等操作。我们可以在拦截器的intercept方法中获取到请求的参数,然后根据需求进行修改。 拦截器可以被添加到OkHttpClient的拦截器链中,通过addInterceptor()方法来添加。当发起网络请求时,拦截器会按照添加的顺序进行拦截。这样,我们就可以在请求中添加或修改参数。 拦截器还可以对响应进行处理,比如对返回的数据进行解析、转换等操作。拦截器可以获取到响应的数据,然后可以对数据进行一些处理,并返回给调用方。 通过使用拦截器,我们可以在不修改原有的网络请求代码的情况下,对请求和响应进行一些通用的处理。这样可以提高开发的效率,并且可以保持代码的整洁和可维护性。 总的来说,Android Retrofit拦截器功能非常强大,可以非常方便地对网络请求的参数进行拦截和修改,提供了非常灵活的扩展性。 ### 回答3: 在Android中,Retrofit是一个广泛使用的网络请求库,用于方便地从服务器获取数据。拦截参数是指在使用Retrofit发送网络请求之前,可以通过拦截器请求的参数进行修改或添加一些额外的信息。 在Retrofit中,可以通过自定义拦截器来实现对参数的拦截操作。拦截器是一个接口,它提供了两个方法:intercept和proceed。 intercept方法用于处理拦截逻辑,我们可以在这个方法中获取到请求的参数信息,并对其进行修改或添加额外信息。可以使用request.body()方法获取请求体,再通过request.newBuilder()方法创建一个新的请求,最后通过chain.proceed()方法继续请求的发送。 proceed方法表示继续发送原始请求,如果不调用该方法,请求将会被拦截,不会发送到服务器。 要使用拦截器,首先需要创建一个OkHttpClient对象,并通过addInterceptor方法将拦截器添加到OkHttpClient中。然后将创建的OkHttpClient对象传递给Retrofit.Builder的client方法。 以下是一个示例代码,演示如何使用拦截器请求参数进行拦截: ``` OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); // 获取原始请求的参数 HttpUrl url = request.url().newBuilder() .addQueryParameter("key", "value") .build(); Request newRequest = request.newBuilder() .url(url) .build(); return chain.proceed(newRequest); } }); OkHttpClient client = builder.build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .client(client) .build(); ``` 上述代码创建了一个OkHttpClient对象,并添加了一个拦截器。在拦截器的intercept方法中,获取了原始请求的参数,然后对其进行了修改(添加了一个名为key值为value的参数),最后调用chain.proceed方法继续发送请求。 通过拦截器,我们可以对请求的参数进行灵活处理,例如对请求进行签名、添加公共参数等操作,提高了开发的灵活性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值