Skip to content Skip to sidebar Skip to footer

Retrofit - Add Field Dynamically During Serialization

I'm currently using Retrofit 2.3 in my Android project and recently the API we are using was updated so that it needs to have 'version':number in JSON body in all POST requests. So

Solution 1:

I did it but not exactly the way you want, you can create BaseRequest POJO class in which you can use version number and extend that class to other POJO classes you are using like this :

classBaseRequest{
@SerializedName("version")publicint version= 0;
 }

Extend this base POJO class is to other POJO classes to use the version number like this :

classUserRequestextendsBaseRequest{
  @SerializedName("username")publicStringuserName="";
  @SerializedName("password")publicStringpassword="";
}

There are lots of benefits of this approach like if you need one more field in your APIs then you don't need to change all of the apis. You can achieve that just by adding a field in your baserequest.

Solution 2:

Resolved this issue with custom interceptors for OkHTTP client. So I've created custom interceptor that would analyze outgoing request and alter its body JSON data if it meets certain criteria.

okHttpClientBuilder.addInterceptor(CustomInterceptor(1))

Works like a charm!

import okhttp3.Interceptor
import okhttp3.RequestBody
import okhttp3.Response
import okio.Buffer
import org.json.JSONException
import org.json.JSONObject
import java.io.IOException

classCustomInterceptor(privateval version: Int): Interceptor {
    overridefunintercept(chain: Interceptor.Chain): Response {
        var request = chain.request()
        val requestBody = request.body()
        val subtype = requestBody?.contentType()?.subtype()
        if(subtype != null
                && subtype.contains("json")) {
            val bodyWithToken = addVersionParamToJSONBody(requestBody)
            if(null != bodyWithToken){
                val requestBuilder = request.newBuilder()
                request = requestBuilder
                        .post(bodyWithToken)
                        .build()
            }
        }
        return chain.proceed(request)
    }

    privatefunaddVersionParamToJSONBody(requestBody: RequestBody?) : RequestBody? {
        val customRequest = bodyToString(requestBody)
        returntry{
            val jsonObject = JSONObject(customRequest)
            jsonObject.put("version", version)
            RequestBody.create(requestBody?.contentType(), jsonObject.toString())
        } catch (e: JSONException){
            e.printStackTrace()
            null
        }
    }

    privatefunbodyToString(requestBody: RequestBody?): String{
        returntry {
            val buffer = Buffer()
            requestBody?.writeTo(buffer)
            buffer.readUtf8()
        } catch (e: IOException){
            e.printStackTrace()
            ""
        }
    }
}    

Post a Comment for "Retrofit - Add Field Dynamically During Serialization"