GSON - json to generic object - json

I have a use case where an API will get a generic collection of Key|Value pairs in json. There are no defined attributes in the input json. I need to map it to a generic object and process the data..
JSON input:
"[{ "PostalCode": "345", "Region": "MA", "Enabled": "True" },
{"PostalCode": "989", "Country": "US", "Enabled": "True" }
]";
I am using GSON to deserialize this to java object. On mapping this to a generic object like:
Object obj = new GsonBuilder().create()
.fromJson(jsonInput, Object.class);
i get a an object of Array list of HashMaps (com.google.gson.internal.LinkedTreeMap).
From here how do i get individual key and values like key = PostalCode & value = 345?
Thanks in advance for your help!

As you have already got an array list of com.google.gson.internal.LinkedTreeMap, Now you need to iterate this list to get each key value pair :
Object obj = new GsonBuilder().create().fromJson(jsonInput, Object.class);
List<LinkedTreeMap<Object, Object>> jsonMapList = (List<LinkedTreeMap<Object, Object>>) obj;
for (LinkedTreeMap<Object, Object> jsonMap : jsonMapList) {
Set<Entry<Object, Object>> entrySet = jsonMap.entrySet();
for (Entry<Object, Object> entry : entrySet) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}

You can do this way. I have tested it.
import this
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
Type type = new TypeToken<List<LinkedTreeMap<Object, Object>>>(){}.getType();
List<Map<Object, Object>> treeMap = newGsonBuilder().create().fromJson(jsonInput,type);

Related

How to get a nested specific json property with Kotlinx serialization in Ktor Kotlin without a data class?

I'm writing an web app with Kotlin and Ktor and I want to parse the json response from Google Books Api and select some specific values from it to store.
For serialization I am using Kotlinx serialization.
I want to avoid creating a data class
The json response from the api is nested and looks like this (Json has been shortened for clarity):
{
"kind": "books#volumes",
"totalItems": 795,
"items": [{
"kind": "books#volume",
"id": "zYw3sYFtz9kC",
"etag": "ylNs2Stlgis",
"selfLink": "https://www.googleapis.com/books/v1/volumes/zYw3sYFtz9kC",
"volumeInfo": {
"title": "The Contemporary Thesaurus of Search Terms and Synonyms",
"subtitle": "A Guide for Natural Language Computer Searching",
"authors": [
"Sara D. Knapp"
],
"publisher": "Greenwood Publishing Group",
"publishedDate": "2000"
}
}]
}
So how can I access the title property in this json with Kotlin / Kotlinx? I get the json object in items, but couldn't go until title.
That's my code so far after calling the api.
Routing.kt:
val response: HttpResponse = client.get("https://www.googleapis.com/books/v1/volumes?q=isbn:$isbn")
println(response.status)
val stringBody: String = response.body()
val json: Map<String, JsonElement> = Json.parseToJsonElement(stringBody).jsonObject
//println(json)
val item = json["items"]
//println(item)
You can cast JsonElement objects to more concrete types to retrieve necessary information:
val obj = Json.parseToJsonElement(stringBody) as JsonObject
val items = obj["items"] as JsonArray
for (item in items) {
val info = (item as JsonObject)["volumeInfo"]
val title = (info as JsonObject)["title"].toString()
println(title)
}
I solved it on this way. So I get the title of the book in variable "title":
val stringBody: String = response.body()
val json: Map<String, JsonElement> = Json.parseToJsonElement(stringBody).jsonObject
val items = json["items"]!!.jsonArray
val item = items[0]
val itemInfo = item.jsonObject
val volumeInfo = itemInfo["volumeInfo"]
val volumeInfoObject = volumeInfo?.jsonObject
val title = volumeInfoObject?.get("title")
println("d: $title")

Iterate through JSONObject

I am working on writing a groovy script now and I am absolute new in groovy lang.
I have Json Object, like that:
{
"firstVar": {
"active": "false",
"title": "First Var"
},
"secondVar": {
"active": "false",
"title": "Second Var"
}
}
I need to iterate over this Json object. Count of items in this object may be various, like "sixthVar". I know solution in Java, and need something similar in groovy:
JSONObject jsonObject = new JSONObject(contents.trim());
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
String key = keys.next();
if (jsonObject.get(key) instanceof JSONObject) {
// do something with jsonObject here
}
}
Or maybe there are some way to convert Json object to Json array?
I found the solution by trial and error. There is way of iteration like in Json Array:
jsonObject.each {
// do something with it.key and it.value pair
}

Gson for mixed values (boolean, int, String) from a Map

I'm creating JsonObject from Map<String, String> with Gson:
val params = HashMap<String, String>()
params["confirmation"] = "send"
JsonParser().parse(Gson().toJson(params)) as JsonObject
It works fine when all entries are Strings (hence the Map<String, String>). However, I find myself unable to use this method to create a mixed-value Json, such as it the following example:
{
"integer": 1,
"string": "text",
"boolean": false
}
Is there a way of accomplishing such results without creating models and POJOs? I found some workarounds, but I'm looking forward to see an elegant solution, maybe a Map with generic (or even wildcard) types..
So, basically I found an answer by trial-and-error method. It was all about extending the parametrized type to Any (Object in Java). Here is how it works:
val params = HashMap<String, Any>()
params["integer"] = 123
params["string"] = "text"
params["boolean"] = false
JsonParser().parse(Gson().toJson(params)) as JsonObject
This code results in a mixed typed JsonObject, as follows:
{
"integer": 123,
"string": "text",
"boolean": false
}

I'm trying to convert my Json Object to pretty format using gson but encountering something odd

JsonObjectBuilder builder = factory.createObjectBuilder().add("input", input);
JsonObject jsonData = builder.build();
String jsonDataString = jsonData.toString();
try {
OutputStream jsonStream = new FileOutputStream(jsonPath);
OutputStreamWriter jsonStreamWriter = new OutputStreamWriter(jsonStream);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String prettyOutput = gson.toJson(jsonData);
System.out.println(prettyOutput);
jsonStreamWriter.write(prettyOutput);
}
catch(Exception e) {}
The output I get is weird:
It adds '"value":' before every string value of a key.
My JSON data is something like this:
{
"input": {
"record0": {
"Active": "",
"Level": "",
"Name": "Pre-Session",
"Description": "",
"Record": "",
"Field": "",
"Std. Rule": "",
"Ext. Rule": "//Updated By: Sukanya Dasgupta On: 25-Jan-2016"
}
}
}
Not an expect but I think the problem is that public String toJson(Object src) loses type information :
This method should be used when the specified object is not a generic
type. This method uses Object.getClass() to get the type for the
specified object, but the getClass() loses the generic type
information because of the Type Erasure feature of Java.

how to add json object to a json element in spring

i want to make a json object where it looks like
{
"version": "1.0",
"message": {
"ID": "test",
"Text": "Acd"
}
}
i need to post this data to server i am trying to add a json object to a json object how to do it
org.json.JSONObject json = new org.json.JSONObject();
org.json.JSONObject root = new org.json.JSONObject();
root.put("version", "1.0");
json.put("ID", "test");
json.put("Text", "acd");
root.put("message", json);
i am getting root.put is not a method for(string,jsonobject)
Create a Map for nested json object, like this:
Map json = new HashMap();
org.json.JSONObject root = new org.json.JSONObject();
root.put("version", "1.0");
json.put("ID", "test");
json.put("Text", "acd");
root.put("message", json);
According to doc:
Put a key/value pair in the JSONObject, where the value will be a
JSONObject which is produced from a Map.