10

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 :)

1
  • I guess the second error I'm getting is because of the empty arrays found in keys like followed_tag_names , but this should be handled by the parser wouldn't it? Commented Mar 25, 2020 at 14:20

3 Answers 3

14

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

Sign up to request clarification or add additional context in comments.

1 Comment

Really appreciate it, simple solution and it works perfectly.
7

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.

3 Comments

IMHO that's the best answer. Simple, and uses a library from the Kotlin repo itself.
problem with this is its a Map<String,JsonElement> – you need to map further and recursively to get it to Kotlin/Java primitives/structures
You can provide your own custom serializers as per requirements.
0

To do it in Klaxon, you can do:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.