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 :)
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,
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.
To do it in Klaxon, you can do:
Klaxon().parse<Map<String,Any>>(jsonString)!!
I am new to groovy Grails and trying to understand how to work with GORM
We have SQL table with column of string type that holds JSON String representing some object
(I can't alternate db design)
I understand that in groovy Model objects represent SQL records and in general we can use marshallers to render objects to JSON
But what I need is to get, create or save Model object that have Json string column that will be rendered to an object in groovy, but can't find any information on how to do it
for example to simplify i will have following table : id(number), json(longstring)
and in JSON:
{"name":"object1", "list":[{"item":"item1", "type":"type1"},{"item":""item2", "type":"type2"},..]}
and following classes:
class MainModelClass {
Long id
MyObject o
...
}
class MyObject {
List<Item> items
...
}
class Item {
String item
String type
...
}
How can I make the Model object parse the JSON to Object structure
Thanks
You could use a simple trick with a transient property like so:
import groovy.json.*
class MainModelClass {
String originalJson
static final JsonSlurper slurper = new JsonSlurper()
MyObject getMyObject(){
slurper.parseText( originalJson ) as MyObject
}
void setMyObject( MyObject myObject ){
originalJson = JsonOutput.toJson myObject
}
static transients = [ 'myObject' ]
}
You might want to use Jackson Mapper to have finer control over marshalling.
I have a unique requirement where i need to construct a JSON as below.
{
"XXXMonitoring/DC/EVN/DBNAME":{
"t":123456777,
"s":{
"CAPTURE":{
"c":100
}
}
}
}
where the root element "XXXMonitoring/DC/EVN/DBNAME" contains "/" in between as it represents a path. I tried with GSON to have nested java but not sure how i can represent "XXXMonitoring/DC/EVN/DBNAME" from my Java object.
Can someone help me on this.
I'm not sure if this is what are you asking...
But sollidus (/) is escaped by backslash (\) to be sure that the browser won’t mistake it for the closing script tag
when you need to use that key, you can remove backslash with String.replaceAll() method
json.toString().replaceAll("\\\\", "");
The JSON string can be constructed without POJO class using the below code.
If the JSON structure is same and only values will change for the keys, you can replace the hard coded values with variables and convert this into an utility method. The utility method can be reused to generate the JSON string.
public static void main(String[] args) throws IOException {
Gson gson = new Gson();
JsonObject jsonRootObject = new JsonObject();
JsonObject jsonFirstLevelObject = new JsonObject();
// t property
jsonFirstLevelObject.addProperty("t", 123456777);
JsonObject jsonCaptureObject = new JsonObject();
JsonObject jsonCObject = new JsonObject();
jsonCObject.addProperty("c", 100);
jsonCaptureObject.add("CAPTURE", jsonCObject);
// s property
jsonFirstLevelObject.add("s", jsonCaptureObject);
jsonRootObject.add("XXXMonitoring/DC/EVN/DBNAME", jsonFirstLevelObject);
System.out.println(gson.toJson(jsonRootObject));
}
I have a library called GsonPath which might suit your needs. The aim of the library is to provide an annotation processor that generates the boilerplate code to help simplify the POJO you need to write.
By using the library you can write a POJO similar to the following:
#AutoGsonAdapter(rootField = "XXXMonitoring/DC/EVN/DBNAME")
public class SamplePojo {
int t;
#SerializedName("s.CAPTURE.c")
int sCapture;
}
Then all you need to do in your gson object is to register a special TypeAdapterFactory
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapterFactory(GsonPath.createTypeAdapterFactory());
Gson gson = builder.create();
The documentation within the library is faily comprehensive, let me know if you have any problems!
I am using jackson json api to map json data to java objects. All is well in case of same object attribute names with json attributes. Now i have a situation where i am getting json data attribute with -. (my-name).
In java we can't include - in variable names.
import org.codehaus.jackson.map.ObjectMapper;
private static final ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue("{my-name:\"abcd\"}", User.class);
public class User {private String my_name; /*get-set methods*/}
Is there anything i need to apply in User.class.
I don't want to change my code so much.
In your java class you can give any name as you like
Ex. private String myName;
But in the setter method just write:
#JsonProperty("my-name")
public void setMyName(String myName) {
this.myName = myName;
}
So I have a class that I was planning on using for simple JSON serialization.
public class Thing {
private int field1;
private String some_other_field;
private List<SubType> subs;
private list<AnotherType> another;
public String toJson() {
Gson g = new Gson();
g.toJson(this);
}
}
So the documentation shows that if you want to serialize generic types, you need to specify a TypeToken:
Type listtype = new TypeToken<List<SubType>>() {}.getType();
gson.toJson(subs, listtype);
But then, how does this work if I have a whole class I want to serialize for? Where do I get to specify the serialization type for those two List<> types so that I can just pass the whole object in and get a serialized output? Is that even possible?
From the doc it seems that if you serialize a complete object with toJson(...), it deals with the generics attributes properly.
toJson(Object)
"Note that this method works fine if the any of the object fields are of generic type, just the object itself should not be of a generic type"
What output did you get with your object ?