Send complex object using Retrofit2

别说谁变了你拦得住时间么 提交于 2020-05-17 07:43:05

问题


I'm trying to send a complex object as a parameter of my request using Retrofit2 and Kotlin. Structure of that object is the following:

{
  "id": "..."
  "token": "..."
  "message": "..."
  "list1": [
    { "id": 1, "value": 2 },
    { "id": 2, "value": 5 }
    //and so on...
  ]
  "list2": [
    { "id": 10, "value": 16 },
    { "id": 11, "value": 21 }
    //and so on...
  ]
  //and so on...
}

The number of list fields is various(could be 2 lists, could be 10) as well as the number of items inside each list. I'm using the following code to achieve that, previously filled my Map with the appropriate values:

@JvmSuppressWildcards
@FormUrlEncoded
@POST("get_data.php")
fun getResponse(
    @FieldMap params: Map<String, Any>
): Observable<ResponseModelResult>

For some reason that approach is not working properly and the server just ignoring my params. I've also tried to send them as @Body string/object, but it seems like the server accepts only FormUrlEncoded data.

Can someone give me an example how I should send such data as parameter using the @FieldMap approach?


回答1:


YIf you provide demo url of your api or documentation or something else that would help me find out the problem more specific then I will update my answer according to your api mechanism, now you can try this:

Declare your api interface like this:

    @POST("get_data.php") 
    fun getResponse(@Query("params") params: String): Observable<ResponseModelResult>

Make your complex object like this:

    val jsonObject1 = JsonObject().apply {
        addProperty("id", 1)
        addProperty("value", 1)
    }

    val jsonObject2 = JsonObject().apply {
        addProperty("id", 2)
        addProperty("value", 2)
    }

    val list1 = JsonArray().apply {
        add(jsonObject1)
        add(jsonObject2)
    }

    val jsonObject10 = JsonObject().apply {
        addProperty("id", 10)
        addProperty("value", 16)
    }

    val jsonObject11 = JsonObject().apply {
        addProperty("id", 11)
        addProperty("value", 21)
    }

    val list2 = JsonArray().apply {
        add(jsonObject10)
        add(jsonObject11)
    }

    val params = JsonObject().apply {
        addProperty("id", "...")
        addProperty("token", "...")
        addProperty("message", "...")
        add("list1", list1)
        add("list2", list2)
    }.toString()

Here you are ready to go now, call your api passing params as query parameter like: getResponse(params)




回答2:


instead of @FieldMap you can use @Field like below.

@JvmSuppressWildcards @FormUrlEncoded @POST("get_data.php") fun getResponse( @Field("your key") jsonObject: String ): Observable

Pass the json object as string.




回答3:


Finally, I found a solution. Seems like retrofit can't deal with the <String, Any> map, so the easiest way would be to send request parameters in a similar way as, for example, in Postman.

val params = mutableMapOf<String, String>()
params["id"] = ...
params["token"] = ...
params["message"] = ...

params["list1[0][id]"] = "${1}"
params["list1[0][value]"] = "${2}"
params["list1[1][id]"] = "${2}"
params["list1[1][value]"] = "${5}"

params["list2[0][id]"] = "${10}"
params["list2[0][value]"] = "${16}"

//and so on

Then, in my ApiService:

@Headers("Content-Type: application/x-www-form-urlencoded")
@FormUrlEncoded
@POST("get_data.php")
fun getResponse(
    @FieldMap params: Map<String, String>
): Observable<ResponseModelResult>

Probably, that's not the best approach overall, but at least it works for me.



来源:https://stackoverflow.com/questions/61319947/send-complex-object-using-retrofit2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!