改造Android-拦截所有请求获取/放置/发布/删除
向所有的开发者们致意。 我有一个已经在playstore上发布的应用程序,它使用改型作为网络接口。 现在我遇到了一个需求,在这个需求中,我必须在通过应用程序的所有请求中发送一个参数,无论请求是GET/PUT/POST/DELETE。在GET/PUT/DELETE的情况下,我将发送额外的参数作为查询参数,但在POST中,我将其添加到正文中。请参阅下面的代码-改造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
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)
}
}
这实际上取决于您的服务器期望得到什么,没有一种方法可以将一段数据添加到任何主体类型。