2

Inside my Android kotlin app i'm calling some apis by using retrofit2 like

@FormUrlEncoded
@POST("something/some")
fun callMyApi(
    @Field("myField") myField: String
): Deferred<MyResponseClass>

Now i need to add some common post params to all my api request (and keep the specific ones for each call, in this case i need to keep "myField"), so i'm using an interceptor:

val requestInterceptor = Interceptor { chain ->
    val newRequest = chain.request()
        .newBuilder()
        .post(
            FormBody.Builder()
            .add("common1Key", "common1")
            .add("common2Key", "common2")
            .add("common3Key", "common3")
            .build()
         )
         .build()

    return@Interceptor chain.proceed(newRequest)
}

But this implementation fails because the interceptor seems to overwrite myField. How can i fix it?

giozh
  • 9,868
  • 30
  • 102
  • 183
  • You may need to create the copy of your request body first, then create the new FormBody builder with the field which you want to keep common for every request and then append the first request body with the newly created request body. https://stackoverflow.com/questions/34791244/retrofit2-modifying-request-body-in-okhttp-interceptor – Sarvesh Athawale Mar 05 '19 at 10:16

2 Answers2

1

We can create Interceptor by using two or more common query parameter.

val requestInterceptor = Interceptor { chain ->

            val url = chain.request()
                .url()
                .newBuilder()
                .addQueryParameter("common1key", "common1")
                .addQueryParameter("common2key", "common2")
                .addQueryParameter("common3key", "common3")
                .build()
            val request = chain.request()
                .newBuilder()
                .url(url)
                .build()

            return@Interceptor chain.proceed(request)
        }
Ahasan
  • 41
  • 5
1

I have added Interceptor for post form body.

interface PostWebApiService {  

@POST("posts")
@FormUrlEncoded
fun savePost(
    @Field("title") title: String
): Deferred<Post>

companion object {
    operator fun invoke(): PostWebApiService {
        val requestInterceptor = Interceptor { chain ->
            var request = chain.request()

            val requestBuilder = request.newBuilder()
            val formBody = FormBody.Builder()
                .add("body", "Body")
                .add("userId", "12")
                .build()
            var postBodyString = bodyToString(request.body())
            val concat = if (postBodyString.isNotEmpty()) "&" else ""
            postBodyString = postBodyString + concat + bodyToString(formBody)
            request = requestBuilder.post(
                RequestBody.create(
                    MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"),
                    postBodyString
                )
            )
                .build()
            return@Interceptor chain.proceed(request)
        }
        val okHttpClient = OkHttpClient.Builder()
            .addInterceptor(requestInterceptor)
            .build()
        return Retrofit.Builder()
            .client(okHttpClient)
            .baseUrl("http://jsonplaceholder.typicode.com/")
            .addCallAdapterFactory(CoroutineCallAdapterFactory())
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(PostWebApiService::class.java)
    }

    fun bodyToString(request: RequestBody?): String {
        try {
            var buffer = Buffer()
            request?.writeTo(buffer)
            return buffer.readUtf8()
        } catch (e: IOException) {
            return "error"
        }
    }
}
}
Ahasan
  • 41
  • 5