如何使用 Retrofit2 将 Map<String, Any> 作为参数传递?
How to pass Map<String, Any> as parameter using Retrofit2?
我需要传递 Map<String, Any>
作为 PUT 请求的参数。 Json(由地图制作)看起来像这样:
{
"user": {
"lastname": "Smith",
"name": "John",
...
},
"foreign_language_keys": [
"eng",
"fr"
],
"tachograph_cards": [
{
"tachograph_key": "estr",
"tachograph_card_num":
.....
如果我将 Map<String, String>
作为参数传递 - 它工作正常:
@FormUrlEncoded
@Headers("Content-Type: application/json")
@PUT("api/authorization/user/driver/{user_id}")
fun editUser(@Path("user_id") userId: String, @FieldMap body: Map<String, String>): Single<UserModel>
但是如果我需要将 Map<String, Any>
作为参数传递 - 我会收到运行时错误 "java.lang.IllegalArgumentException: Parameter type must not include a type variable or wildcard: java.util.Map (parameter #2)"
添加 @JvmSuppressWildcards 注释 (@FieldMap body: Map<String, @JvmSuppressWildcards Any>)
) 没有帮助(我从服务器收到另一个错误 "Undefined index" Json 中的一个必要字段,因为服务器没有看到该字段根据我的要求)。
可行的解决方案是通过映射我模型中的所有字段(而不是传递 Map<String, Any>
)来制作 com.google.gson.JsonObject,但这太难了。我确信它必须在不将我的模型转换为 Json 的情况下工作,但我找不到简单的解决方案。
有人可以帮忙吗?
您的 JSON 结构看起来很奇怪且不一致。您通过 Retrofit 的结构,您需要定义清晰一致的结构。在您的情况下,您的地图键看起来总是 String 但地图的值部分有时是 Json 对象,有时是 array/list 或其他任何东西。不一致,因此无法确定结构化值。
你肯定不能 post/put Map<String, Any
因为 ?是非法参数。
您可以构造和发送 Map<String, JsonObject>
,如果您使用 Gson 库,Json对象的创建并不难。您所做的就是提取字符串(Json 对象的值部分)并将其提供给 Gson 库,然后它生成 JsonObject 模型供您传递。
或者您可以从解析端发送 Map<String, String>
,您 parse()
和 stringify(
) 的 Json 值,
我最近遇到了同样的问题,我找到了可能是最简单的解决方案。
您可以在此处查看我对类似问题的完整回答:
在你的具体情况下,你可以试试这个:
val body = mutableMapOf<String, String>()
body["user[lastname]"] = "Smith"
body["user[name]"] = "John"
body["foreign_language_keys[0]"] = "eng"
body["foreign_language_keys[1]"] = "fr"
// and so on
如果您需要传递一个巨大的动态列表,您可以轻松地在 for
循环中填充您的地图,例如。
它必须是一个可变变量作为委托 属性。能够用 Any
来惩罚你想要放置的 属性
你的解决方案是把 MutableMap
interface MutableMap<K, V>
V the type of map values. The mutable map is invariant in its value type.
interfaceMap<K, V>
V the type of map values. The map is covariant in its value type.
@FormUrlEncoded
@Headers("Content-Type: application/json")
@PUT("api/authorization/user/driver/{user_id}")
fun editUser(@Path("user_id") userId: String, @FieldMap body: MutableMap<String, String>): Single<UserModel>
我需要传递 Map<String, Any>
作为 PUT 请求的参数。 Json(由地图制作)看起来像这样:
{
"user": {
"lastname": "Smith",
"name": "John",
...
},
"foreign_language_keys": [
"eng",
"fr"
],
"tachograph_cards": [
{
"tachograph_key": "estr",
"tachograph_card_num":
.....
如果我将 Map<String, String>
作为参数传递 - 它工作正常:
@FormUrlEncoded
@Headers("Content-Type: application/json")
@PUT("api/authorization/user/driver/{user_id}")
fun editUser(@Path("user_id") userId: String, @FieldMap body: Map<String, String>): Single<UserModel>
但是如果我需要将 Map<String, Any>
作为参数传递 - 我会收到运行时错误 "java.lang.IllegalArgumentException: Parameter type must not include a type variable or wildcard: java.util.Map (parameter #2)"
添加 @JvmSuppressWildcards 注释 (@FieldMap body: Map<String, @JvmSuppressWildcards Any>)
) 没有帮助(我从服务器收到另一个错误 "Undefined index" Json 中的一个必要字段,因为服务器没有看到该字段根据我的要求)。
可行的解决方案是通过映射我模型中的所有字段(而不是传递 Map<String, Any>
)来制作 com.google.gson.JsonObject,但这太难了。我确信它必须在不将我的模型转换为 Json 的情况下工作,但我找不到简单的解决方案。
有人可以帮忙吗?
您的 JSON 结构看起来很奇怪且不一致。您通过 Retrofit 的结构,您需要定义清晰一致的结构。在您的情况下,您的地图键看起来总是 String 但地图的值部分有时是 Json 对象,有时是 array/list 或其他任何东西。不一致,因此无法确定结构化值。
你肯定不能 post/put Map<String, Any
因为 ?是非法参数。
您可以构造和发送 Map<String, JsonObject>
,如果您使用 Gson 库,Json对象的创建并不难。您所做的就是提取字符串(Json 对象的值部分)并将其提供给 Gson 库,然后它生成 JsonObject 模型供您传递。
或者您可以从解析端发送 Map<String, String>
,您 parse()
和 stringify(
) 的 Json 值,
我最近遇到了同样的问题,我找到了可能是最简单的解决方案。
您可以在此处查看我对类似问题的完整回答:
在你的具体情况下,你可以试试这个:
val body = mutableMapOf<String, String>()
body["user[lastname]"] = "Smith"
body["user[name]"] = "John"
body["foreign_language_keys[0]"] = "eng"
body["foreign_language_keys[1]"] = "fr"
// and so on
如果您需要传递一个巨大的动态列表,您可以轻松地在 for
循环中填充您的地图,例如。
它必须是一个可变变量作为委托 属性。能够用 Any
来惩罚你想要放置的 属性你的解决方案是把 MutableMap
interface MutableMap<K, V>
V the type of map values. The mutable map is invariant in its value type.
interfaceMap<K, V>
V the type of map values. The map is covariant in its value type.
@FormUrlEncoded
@Headers("Content-Type: application/json")
@PUT("api/authorization/user/driver/{user_id}")
fun editUser(@Path("user_id") userId: String, @FieldMap body: MutableMap<String, String>): Single<UserModel>