Parse JSON String to JsonObject/Map/MutableMap in Kotlin

Viewed 9819

I'm fairly new to Kotlin and I'm having trouble manipulating a basic JSON string to access its contents. The JSON string looks like this:

"{\"id\":24,\"name\":\"nope\",\"username\":\"unavailable1991\",\"profile_image_90\":\"/uploads/user/profile_image/24/23102ca5-1412-489d-afdf-235c112c7d8e.jpg\",\"followed_tag_names\":[],\"followed_tags\":\"[]\",\"followed_user_ids\":[],\"followed_organization_ids\":[],\"followed_podcast_ids\":[],\"reading_list_ids\":[],\"blocked_user_ids\":[],\"saw_onboarding\":true,\"checked_code_of_conduct\":true,\"checked_terms_and_conditions\":true,\"number_of_comments\":0,\"display_sponsors\":true,\"trusted\":false,\"moderator_for_tags\":[],\"experience_level\":null,\"preferred_languages_array\":[\"en\"],\"config_body_class\":\"default default-article-body pro-status-false trusted-status-false default-navbar-config\",\"onboarding_variant_version\":\"8\",\"pro\":false}"

I've tried using the Gson and Klaxon packages without any luck. My most recent attempt using Klaxon looked like this:

val json: JsonObject? = Klaxon().parse<JsonObject>(jsonString)

But I get the following error: java.lang.String cannot be cast to com.beust.klaxon.JsonObject

I also tried trimming the double quotes (") at the start and end of the string, and also removing all the backslashes like this:

val jsonString = rawStr.substring(1,rawStr.length-1).replace("\\", "")

But when running the same Klaxon parse I now get the following error: com.beust.klaxon.KlaxonException: Unable to instantiate JsonObject with parameters []

Any suggestions (with or without Klaxon) to parse this string into an object would be greatly appreciated! It doesn't matter if the result is a JsonObject, Map or a custom class, as long as I can access the parsed JSON data :)

3 Answers

Gson is perfect library for this kinda task, here how to do it with gson.

Kotlin implementation,

var map: Map<String, Any> = HashMap()
map = Gson().fromJson(jsonString, map.javaClass)

Or if you want to try with Java,

Gson gson = new Gson(); 
Map<String,Object> map = new HashMap<String,Object>();
map = (Map<String,Object>) gson.fromJson(jsonString, map.getClass());

And also I just tried with your json-string and it is perfectly working,

enter image description here

To do it in Klaxon, you can do:

Klaxon().parse<Map<String,Any>>(jsonString)!!

Kotlin now provides a multiplatform / multi-format reflectionless serialization.

plugins {
    kotlin("jvm") version "1.7.10" // or kotlin("multiplatform") or any other kotlin plugin
    kotlin("plugin.serialization") version "1.7.10"
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0")
}

So now you can simply use their standard JSON serialization library:

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject

fun main() {
    val jsonString = "{\"id\":24,\"name\":\"nope\",\"username\":\"unavailable1991\",\"profile_image_90\":\"/uploads/user/profile_image/24/23102ca5-1412-489d-afdf-235c112c7d8e.jpg\",\"followed_tag_names\":[],\"followed_tags\":\"[]\",\"followed_user_ids\":[],\"followed_organization_ids\":[],\"followed_podcast_ids\":[],\"reading_list_ids\":[],\"blocked_user_ids\":[],\"saw_onboarding\":true,\"checked_code_of_conduct\":true,\"checked_terms_and_conditions\":true,\"number_of_comments\":0,\"display_sponsors\":true,\"trusted\":false,\"moderator_for_tags\":[],\"experience_level\":null,\"preferred_languages_array\":[\"en\"],\"config_body_class\":\"default default-article-body pro-status-false trusted-status-false default-navbar-config\",\"onboarding_variant_version\":\"8\",\"pro\":false}"

    Json.parseToJsonElement(jsonString) // To a JsonElement
        .jsonObject                     // To a JsonObject
        .toMutableMap()                 // To a MutableMap
}

See: Kotlin Serialization Guide for further details.

Related