【问题标题】:Retrofit Android - Intercept all requests GET/PUT/POST/DELETERetrofit Android - 拦截所有请求 GET/PUT/POST/DELETE
【发布时间】:2020-10-21 10:49:15
【问题描述】:

向所有开发人员致敬。 我有一个已经在 Playstore 上发布的应用程序,并使用改造作为网络接口。 现在我遇到了一个要求,我必须在通过应用程序的所有请求中发送一个参数,无论请求是 GET/PUT/POST/DELETE。在 GET/PUT/DELETE 的情况下,我将发送额外的参数作为查询参数,但在 POST 中,我将其添加到正文中。请参阅下面的代码 -

class CommonParamsInterceptor : Interceptor {
companion object {
    const val EXTRA_PARAM = "extra_param"
}

override fun intercept(chain: Interceptor.Chain): Response {
    val request = chain.request()
    return chain.proceed(
                when (request.method()) {
                    HTTP_METHOD_GET, HTTP_METHOD_PUT, HTTP_METHOD_DELETE -> {
                        val url = request.url()
                        request.newBuilder()
                            .url(
                                url.newBuilder()
                                    .addQueryParameter(EXTRA_PARAM, "param_value")
                                    .build()
                            )
                            .build()
                    }
                    HTTP_METHOD_POST -> {
                        val body = request.body()
                        request.newBuilder()
                            .post(
                                RequestBody.create(
                                    body?.contentType(),
                                    body.bodyToString() + "&" + EXTRA_PARAM + "=" + "param_value"
                                )
                            )
                            .build()
                    }
                    else -> request
                }
            )
        }
    }




private fun RequestBody?.bodyToString(): String {
    if (this == null) return ""
    val buffer = okio.Buffer()
    writeTo(buffer)
    return buffer.readUtf8()
}

现在的问题是我的一些帖子请求可能没有正文或可能有地图或可能有 json 作为内容。 那么无论正文类型如何,如何在所有发布请求中添加 PARAM?提前致谢。

【问题讨论】:

  • 这真的取决于您的服务器期望得到什么,没有一种方法可以将一条数据添加到任何主体类型。

标签: android kotlin http-post retrofit2 interceptor


【解决方案1】:

为了将来参考,发布我的解决方案版本。

class CommonParamsInterceptor : Interceptor {
companion object {
    const val PARAM_EXTRA = "extra_param"
    const val TYPE_FORM = "form"
    const val TYPE_JSON = "json"
}

override fun intercept(chain: Interceptor.Chain): Response {
    val request = chain.request()
    return  chain.proceed(
                when (request.method()) {
                    HTTP_METHOD_GET, HTTP_METHOD_PUT, HTTP_METHOD_DELETE -> {
                        val url = request.url()
                        request.newBuilder()
                            .url(
                                url.newBuilder()
                                    .addQueryParameter(PARAM_EXTRA, "val")
                                    .build()
                            )
                            .build()
                    }
                    HTTP_METHOD_POST -> {
                        var requestBody = request.body()
                        if (requestBody != null) {
                            val subtype = requestBody.contentType()?.subtype()
                            if (subtype?.contains(TYPE_JSON) == true) { /* when it is json */
                                requestBody = processApplicationJsonRequestBody(requestBody)
                            } else if (subtype?.contains(TYPE_FORM) == true) { /* when it is form-data */
                                requestBody = processFormDataRequestBody(requestBody)
                            }
                        } else { /* when we don't have any body*/
                            requestBody = FormBody.Builder()
                                .add(PARAM_EXTRA, "val")
                                .build()
                        }
                        requestBody?.run {
                            request.newBuilder()
                                .post(this)
                                .build()
                        } ?: kotlin.run {
                            request
                        }
                    }

                    else -> request
                }
            )
    }
}

private fun bodyToString(request: RequestBody?): String {
    if (request == null) return ""
    try {
        val buffer = okio.Buffer()
        request.writeTo(buffer)
        return buffer.readUtf8()
    } catch (e: Exception) {
        MerchantLogger.logAndPrintException(e)
        return ""
    }
}

private fun processApplicationJsonRequestBody(
    requestBody: RequestBody
): RequestBody? {
    val customReq = bodyToString(requestBody)
    try {
        val obj = JSONObject(customReq)
        obj.put(PARAM_EXTRA, "val")
        return RequestBody.create(requestBody.contentType(), obj.toString())
    } catch (e: JSONException) {
        e.printStackTrace()
    }
    return null
}

private fun processFormDataRequestBody(
    requestBody: RequestBody
): RequestBody {
    val formBody: RequestBody = FormBody.Builder()
        .add(PARAM_EXTRA,"val")
        .build()
    var postBodyString = bodyToString(requestBody)
    postBodyString += (if (postBodyString.isEmpty().not()) "&" else "") + bodyToString(formBody)
    return RequestBody.create(requestBody.contentType(), postBodyString)
}
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多