Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
改造Android-拦截所有请求获取/放置/发布/删除_Android_Kotlin_Http Post_Retrofit2_Interceptor - Fatal编程技术网

改造Android-拦截所有请求获取/放置/发布/删除

改造Android-拦截所有请求获取/放置/发布/删除,android,kotlin,http-post,retrofit2,interceptor,Android,Kotlin,Http Post,Retrofit2,Interceptor,向所有的开发者们致意。 我有一个已经在playstore上发布的应用程序,它使用改型作为网络接口。 现在我遇到了一个需求,在这个需求中,我必须在通过应用程序的所有请求中发送一个参数,无论请求是GET/PUT/POST/DELETE。在GET/PUT/DELETE的情况下,我将发送额外的参数作为查询参数,但在POST中,我将其添加到正文中。请参阅下面的代码- class CommonParamsInterceptor : Interceptor { companion object { c

向所有的开发者们致意。 我有一个已经在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()
}

现在的问题是,我的一些post请求可能没有body,或者可能有Map,或者可能有json作为内容那么如何在所有post请求中添加参数,而不考虑正文类型?。提前感谢。

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

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)
}
  }

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