How to create a JSONObject from String in Kotlin?

JsonKotlin

Json Problem Overview


I need to convert a string {\"name\":\"test name\", \"age\":25} to a JSONObject

Json Solutions


Solution 1 - Json

Perhaps I'm misunderstanding the question but it sounds like you are already using org.json which begs the question about why

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

wouldn't be the best way to do it? What was wrong with the built in functionality of JSONObject?

Solution 2 - Json

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

Solution 3 - Json

You can use https://github.com/cbeust/klaxon library.

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")}")

Result :

Name : Cedric Beust, Age : 23

Solution 4 - Json

The approaches above are a bit dangerous: They don't provide a solution for illegal chars. They don't do the escaping... And we hate to do the escaping ourselves, don't we?

So here's what I did. Not that cute and clean but you have to do it only once.

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()
}

Sorry, might have had to cut off types that were unique to my code so I might have broken some stuff - but the idea should be clear

You might be aware that in Kotlin, "to" is an infix method that converts two objects to a Pair. So you use it simply like this:

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

But you can do cuter things:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnkukdayView Question on Stackoverflow
Solution 1 - JsonRybaView Answer on Stackoverflow
Solution 2 - Jsonarjun shresthaView Answer on Stackoverflow
Solution 3 - JsonAkshar PatelView Answer on Stackoverflow
Solution 4 - JsonManeki NekoView Answer on Stackoverflow