Android 改装从Map生成错误的GET请求参数<;字符串:任意>;

Android 改装从Map生成错误的GET请求参数<;字符串:任意>;,android,kotlin,retrofit,okhttp3,Android,Kotlin,Retrofit,Okhttp3,我有以下资料: var dict: Map<String, Any> = listOf() dict["p1"] = listOf(1, 3) dict["p2"] = listOf(null, 2.1) dict["p3"] = 1 但它产生的结果如下: uri?staticKey=staticValue& p1=[1, 3]& p2=[null, 2.1]& p3=1 我做错什么了吗?我刚刚开始Kotlin和Android的开发

我有以下资料:

var dict: Map<String, Any> = listOf()
dict["p1"] = listOf(1, 3)
dict["p2"] = listOf(null, 2.1)
dict["p3"] = 1
但它产生的结果如下:

uri?staticKey=staticValue&
    p1=[1, 3]&
    p2=[null, 2.1]&
    p3=1
我做错什么了吗?我刚刚开始Kotlin和Android的开发,所以我不确定翻新/okhttp库是否支持这一点

注意我需要
映射
等功能,以便轻松添加/删除查询参数。

仅对
映射的值调用
toString()
。为了达到你的目的,你必须直接定义它

var dict: Map<String, Any> = listOf()
dict["p1[0]"] = 1
dict["p1[1]"] = 3
dict["p2[0]"] = ""
dict["p2[1]"] = 2.1
dict["p3"] = 1
var dict:Map=listOf()
dict[“p1[0]”=1
dict[“p1[1]”=3
dict[“p2[0]”=
dict[“p2[1]”=2.1
dict[“p3”]=1
只需将地图展平即可绘制地图

fun Map<String, Any>.queryArgs(): Map<String, Any> {
    val map = mutableMapOf<String, Any>()
    forEach { (key, value) ->
        if (value !is Iterable<*>) {
            map[key] = value
        } else value.forEachIndexed { index, value ->
            map["$key[$index]"] = value ?: ""
        }
    }
    return map
}
fun Map.queryArgs():Map{
val map=mutableMapOf()
forEach{(键,值)->
if(值!是可计算的){
映射[键]=值
}else value.ForeAchined{索引,值->
映射[“$key[$index]”]=值:
}
}
返回图
}

这假设最多只有一个级别的列表。

这是我的解决方案


  • HashMap中的原始密钥,以便可以进行更新/删除,例如

    dict.remove("p1")
    dict["p1"] = new value
    
  • 具有嵌套数组的能力,例如

    [
      0: [coord1, coord2, coord3],
      1: [coord1, coord2, coord3]
    ]
    

输出:

p1[0]=1&p1[1]=3&
p2[0]=&p2[1]=2.1&
p3=1&
bbox[0][0]=p1-coord1&bbox[0][1]=p1-coord2&
bbox[1][0]=p2-coord1&bbox[1][1]=p2-coord2&bbox[1][2]=p2-coord3&
bbox[2][0]=p3-coord1&bbox[2][1]=p3-coord2

您所期望的那些数组索引让我感到奇怪——就像实际输出显然不是有效的查询字符串一样。。。如果没有API所期望的参数的实际文档,则无法回答此问题;您所期望的与此无关。一个合适的API可能会接受作为主体发布的
JSON
。。。因为查询字符串a)长度有限,b)看起来相当混乱(比需要的复杂得多)。但是,API规定了结果。@MartinZeitler这些数组索引是可选的,带或不带数组索引都是有效的HTTP get请求参数,下面是一个示例stackoverflow.com/a/3980336/1244597您将正文中的JSON作为POST请求是正确的,但我无法改变我必须使用get请求的情况,因此,我的内容类型不能是JSONit,它在理论上可能确实是“有效的”……但API设计低于标准(因为构建请求的复杂方式可能已经暗示了这一点)。如果您有机会更改API,这可能是一个X/Y问题-如果没有,就没有办法了。在iOS中,我使用了Alamofire和SwiftHTTP,这两个库都提供了开箱即用的功能,这是很常见的情况,下面是具有此功能的上述库的链接查找扩展数组:HTTPParameterProtocol::createPairs
感谢您对改型行为的概述。这将为每个参数创建不同的键,我还需要能够从
Map
中删除一个参数,例如,删除
p1
将删除其所有元素,顺便说一句,我已经更新了我的问题,这些数组索引不是必需的。谢谢你的回复!根据服务器设置,这些实际上是必要的。最好是有。尤其是当您将这些用作贴图关键点时。您可以尝试创建最终只应用的平面贴图。让你的地图与我的价值观融为一体。我不太明白你的意思,你可以尝试创建一个平面地图,但最终你只能应用它。将你的地图与我的价值观整合在一起。如果可能,你能提供一个简短的例子开始,再次感谢你的回答
[
  0: [coord1, coord2, coord3],
  1: [coord1, coord2, coord3]
]
data class URL(val params: MutableMap<String, Any> = mutableMapOf<String, Any>()) {

    override fun toString(): String = params.map {
        val value = it.value
        if (value !is Iterable<*>) {
            it.key + "=" + it.value.toString()
        } else {
            createPairs(it.key, value)
        }
    }.joinToString("&")

    fun createPairs(key: String, value: Iterable<*>): String {
        return value.mapIndexed { idx, value ->
            val useKey = key + "[" + idx + "]"
            if (value !is Iterable<*>) {
                useKey + "=" + (value?.toString() ?: "")
            } else
                createPairs(useKey, value)

        }.joinToString("&")
    }
}
val url = URL()
url.params["p1"] = listOf(1, 3)
url.params["p2"] = listOf(null, 2.1)
url.params["p3"] = 1

val polygon1 = listOf("p1-coord1", "p1-coord2")
val polygon2 = listOf("p2-coord1", "p2-coord2", "p2-coord3")
val polygon3 = listOf("p3-coord1", "p3-coord2")
url.params["bbox"] = listOf(polygon1, polygon2, polygon3)

println(url.toString())
p1[0]=1&p1[1]=3&
p2[0]=&p2[1]=2.1&
p3=1&
bbox[0][0]=p1-coord1&bbox[0][1]=p1-coord2&
bbox[1][0]=p2-coord1&bbox[1][1]=p2-coord2&bbox[1][2]=p2-coord3&
bbox[2][0]=p3-coord1&bbox[2][1]=p3-coord2