java - Java - 将 HTML 参数转换为 JSON
问题描述
我目前正在为一个项目工作,其中数据作为 application/x-www-form-urlencoded 发送到服务器(这很糟糕,它应该是 JSON,但不幸的是我无法更改这个)。
我的问题是,如何将给定的结构转换为 JSON,或者更好的是,将其直接反序列化为对象?
_id=[5bfad95450642c333010daca],
_rev=[1-9ce33949c3acd85cea6c58467e6a8144],
type=[Group],
user=[aUSer],
default=[aDetail],
store[aDetail][prop]=[5],
store[aDetail][lprop1][0][time]=[00:00],
store[aDetail][lprop1][0][value]=[14],
store[aDetail][lprop1][0][timeAsSeconds]=[0],
store[aDetail][lprop1][1][time]=[07:00],
store[aDetail][lprop1][1][value]=[8],
store[aDetail][lprop1][1][timeAsSeconds]=[25200],
store[aDetail][anprop]=[25],
store[aDetail][lprop2][0][time]=[00:00],
store[aDetail][lprop2][0][value]=[61],
store[aDetail][lprop2][0][timeAsSeconds]=[0],
store[bDetail][prop]=[6],
store[bDetail][lprop1][0][time]=[00:10],
store[bDetail][lprop1][0][value]=[12],
store[bDetail][lprop1][0][timeAsSeconds]=[0],
store[bDetail][lprop1][1][time]=[07:10],
store[bDetail][lprop1][1][value]=[9],
store[bDetail][lprop1][1][timeAsSeconds]=[25200],
store[bDetail][anprop]=[25],
store[bDetail][lprop2][0][time]=[00:00],
store[bDetail][lprop2][0][value]=[61],
store[bDetail][lprop2][0][timeAsSeconds]=[0],
created_at=[2018-01-11T20:48:22.574+0100]
在 json 中,这看起来像这样(跳过大部分已经给定的值):
{
_id: 5bfad95450642c333010daca,
_rev: 1-9ce33949c3acd85cea6c58467e6a8144,
type: Group,
user: aUSer,
default: aDetail,
store: [
aDetail: {
prop: 0,
lprop1: [
{
time: 00:00,
value: 14,
timeAsSeconds: 0
}
]
}
]
}
从这种表单格式到 json 的转换是相当烦人的。任何帮助表示赞赏。顺便说一句,我正在使用 Jackson 和 Java 和/或 Kotlin,如果这有帮助的话。
解决方案
我有一个相当幼稚的解决方案,它考虑了嵌套对象和数组。这对我有用,如果在其他环境中使用,可能/将会有一些主要缺点。
解决方案是用 kotlin 编写的,但很可能以不那么复杂的方式编写。
fun parseToMap(map: MutableMap<String, Any>, key: String, value: Any): MutableMap<String, Any> {
val cleanedV = if (value is String) URLDecoder.decode(value, "UTF-8") else value
if (!key.contains("[")) {
map.putIfAbsent(key, cleanedV)
} else {
// mapKey is the key going to get stored in the map
val mapKey = key.substring(0, key.indexOf("["))
// nextKey is the next key pushed to the next call of parseToMap
var nextKey = key.removePrefix(mapKey)
nextKey = nextKey.replaceFirst("[", "").replaceFirst("]", "")
var isArray = false
var index = -1
if (nextKey.contains("[") &&
nextKey.substring(0, nextKey.indexOf("[")).matches(Regex("[0-9]+"))) {
index = nextKey.substring(0, nextKey.indexOf("[")).toInt()
isArray = true
}
// mapkey used for object in list
val newMapKey = if (isArray) nextKey.substring(nextKey.indexOf("[") + 1, nextKey.indexOf("]")) else ""
val child: Any?
var childMap: MutableMap<String, Any> = mutableMapOf()
if (map.containsKey(mapKey)) {
println("key $mapKey exists already")
child = map[mapKey]
when (child) {
is MutableList<*> -> {
if (child == null || child.isEmpty()) {
childMap = mutableMapOf()
val tmpList = child as MutableList<Any>
tmpList.add(childMap)
map.put(newMapKey, tmpList)
} else {
if (child.size > index) {
childMap = child.get(index) as MutableMap<String, Any>
childMap = parseToMap(childMap, newMapKey, value)
} else {
childMap = parseToMap(childMap, newMapKey, value)
val tmpList = child as MutableList<Any>
tmpList.add(childMap)
}
}
}
is MutableMap<*, *> -> childMap = map.get(mapKey) as MutableMap<String, Any>
}
} else {
if (isArray) {
child = mutableListOf<Any>()
childMap = parseToMap(childMap, newMapKey, value)
child.add(childMap)
map.put(mapKey, child)
} else {
childMap = mutableMapOf<String, Any>()
}
}
if (!isArray) parseToMap(childMap, nextKey, value)
map.putIfAbsent(mapKey, childMap)
}
return map
}
应该使用 Map 和每个参数键(就像我的问题中已经提到的那样)以及每个参数的值来调用此方法。
推荐阅读
- github - 如何在本地恢复丢失的更改
- r - partimat - 删除班级干线的分数
- javascript - myFunction 不是函数
- python - 解析和比较列表和字典以及输出值
- java - 使用服务器路径中的 Excel 文件中的 spark 创建 DataFrame
- php - 如何避免 JOIN 查询 PHP PDO 中的重复?
- python - 使用一个可用的库 scapy-cip-enip 向 EIP 设备尝试 EIP 隐式消息传递
- vb.net - 从 AppData\Local\Microsoft\Office\16.0\Lync 拆分出 SIP-Address 的问题
- sql-server - SQL SERVER:如何删除一个表中与其他表具有一对多映射的重复行
- c# - Microsoft Graph 令牌不包含权限,或权限无法理解