使用 Retrofit2 发送复杂对象

Send complex object using Retrofit2

我正在尝试使用 Retrofit2 和 Kotlin 发送一个复杂对象作为我的请求的参数。 该对象的结构如下:

{
  "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...
}

列表字段的数量多种多样(可以是 2 个列表,也可以是 10 个)以及每个列表中的项目数。 我正在使用以下代码来实现这一点,之前用适当的值填充了我的地图:

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

由于某种原因,该方法无法正常工作,服务器只是忽略了我的参数。 我也尝试将它们作为 @Body string/object 发送,但服务器 似乎只接受 FormUrlEncoded 数据 .

有人可以举例说明我应该如何使用 @FieldMap 方法发送此类数据作为参数吗?

Y如果您提供 api 的演示 url 或文档或其他可以帮助我更具体地找出问题的内容,那么我将根据您的 api 更新我的答案机制,现在你可以试试这个:

像这样声明您的 api 接口:

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

像这样制作复杂的对象:

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

现在您可以开始了,调用您的 api 传递 params 作为查询参数,例如:getResponse(params)

您可以使用 @Field 而不是 @FieldMap,如下所示。

@JvmSuppressWildcards @FormUrlEncoded @POST("get_data.php") 有趣的 getResponse( @Field("your key") json对象:字符串 ): 可观察

将 json 对象作为字符串传递。

终于找到了解决办法。似乎改造无法处理 <String, Any> 映射,因此最简单的方法是以类似于 Postman 的方式发送请求参数。

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

params["list1[0][id]"] = ""
params["list1[0][value]"] = ""
params["list1[1][id]"] = ""
params["list1[1][value]"] = ""

params["list2[0][id]"] = ""
params["list2[0][value]"] = ""

//and so on

然后,在我的 ApiService 中:

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

这可能不是总体上最好的方法,但至少对我有用。