Как создать JSONObject из String в Котлине?

Мне нужно преобразовать строку {\"name\":\"test name\", \"age\":25} в объект JSONObject

Ответ 1

Возможно, я не понимаю вопрос, но похоже, что вы уже используете org.json, который задает вопрос о том, почему

val answer = JSONObject("""{"name":"test name", "age":25}""")

не лучший способ сделать это? Что случилось с встроенной функциональностью JSONObject?

Ответ 2

Вы можете использовать https://github.com/cbeust/klaxon библиотеку.

val parser: Parser = Parser()
val stringBuilder: StringBuilder = StringBuilder("{\"name\":\"Cedric Beust\", \"age\":23}")
val json: JsonObject = parser.parse(stringBuilder) as JsonObject
println("Name : ${json.string("name")}, Age : ${json.int("age")}")

Результат:

Name : Cedric Beust, Age : 23

Ответ 3

val rootObject= JSONObject()
rootObject.put("name","test name")
rootObject.put("age","25")

Ответ 4

Подходы, приведенные выше, немного опасны: они не дают решения для незаконных символов. Они не убегают... И мы ненавидим убегать сами, не так ли?

Итак, вот что я сделал. Не так мило и чисто, но вы должны сделать это только один раз.

class JsonBuilder() {
    private var json = JSONObject()

    constructor(vararg pairs: Pair<String, *>) : this() {
        add(*pairs)
    }

    fun add(vararg pairs: Pair<String, *>) {
        for ((key, value) in pairs) {
            when (value) {
                is Boolean -> json.put(key, value)
                is Number -> add(key, value)
                is String -> json.put(key, value)
                is JsonBuilder -> json.put(key, value.json)
                is Array<*> -> add(key, value)
                is JSONObject -> json.put(key, value)
                is JSONArray -> json.put(key, value)
                else -> json.put(key, null) // Or whatever, on illegal input
            }
        }
    }

    fun add(key: String, value: Number): JsonBuilder {
        when (value) {
            is Int -> json.put(key, value)
            is Long -> json.put(key, value)
            is Float -> json.put(key, value)
            is Double -> json.put(key, value)
            else -> {} // Do what you do on error
        }

        return this
    }

    fun <T> add(key: String, items: Array<T>): JsonBuilder {
        val jsonArray = JSONArray()
        items.forEach {
            when (it) {
                is String,is Long,is Int, is Boolean -> jsonArray.put(it)
                is JsonBuilder -> jsonArray.put(it.json)
                else -> try {jsonArray.put(it)} catch (ignored:Exception) {/*handle the error*/}
            }
        }

        json.put(key, jsonArray)

        return this
    }

    override fun toString() = json.toString()
}

Извините, возможно, пришлось обрезать типы, которые были уникальны для моего кода, поэтому я мог испортить некоторые вещи - но идея должна быть ясной

Возможно, вы знаете, что в Kotlin "to" - это инфиксный метод, который преобразует два объекта в пару. Таким образом, вы используете это просто так:

   JsonBuilder(
      "name" to "Amy Winehouse",
      "age" to 27
   ).toString()

Но вы можете делать более приятные вещи:

JsonBuilder(
    "name" to "Elvis Presley",
    "furtherDetails" to JsonBuilder(
            "GreatestHits" to arrayOf("Surrender", "Jailhouse rock"),
            "Genre" to "Rock",
            "Died" to 1977)
).toString()