Java - конвертировать параметры HTML в JSON - PullRequest
0 голосов
/ 29 декабря 2018

В настоящее время я работаю над проектом, где данные отправляются на сервер в виде 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 довольно раздражает.Любая помощь приветствуется.Кстати, я использую Джексона и Java и / или Kotlin, если это поможет.

1 Ответ

0 голосов
/ 30 декабря 2018

У меня довольно наивное решение, которое учитывает вложенные объекты и массивы.Это работает для меня, и могут / будут иметь некоторые существенные недостатки, если используются в других средах.

Решение написано на 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
}

Этот метод должен вызываться с картой и каждым ключом параметра (как описано в моем вопросе уже), а также со значением каждого параметра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...