JSON mapper for Nested objects and arrays - java

I have a Json String from a webservice response.
This JSON sting has nested objects and arrays. I have tried to map it with java objects using jackson and GSON but i am getting errors in both the cases.
This is my Json:
{"events": [{
"Code": "4",
"eventDataSet": {
"Bar":{"EvDesc":"WRAP_UP"},
"Foo":{
"AcssId":"**1234",
"EvCSId":"12ā€Œā€‹34",
"custId":"3501234","Recid":"bknz"
}
}
]}
I want to pull the values of Bar and Foo objects from this json.
Please suggest how can i map such type of responses.

Libraries such as Gson and Jackson shouldn't have any trouble de-serializing valid JSON Strings.
Most probably the problem is with object types you're using to de-serialize your inputs.
You can use this site to generate POJO from one of your JSON responses. Input your JSON and select JSON as Source Type.
Then, with Gson:
Gson gson = new GsonBuilder().create();
Person p = gson.fromJson(inputString, Example.class);

Your json seems to have some problem. Here is modified json, and I am able to convert it to Object using jackson.
{
"events": [{
"code": "4",
"eventDataSet": {
"bar": {
"evDesc": "WRAP_UP"
},
"foo": {
"acssId": "**1234",
"evCSId": "12??34",
"custId": "3501234",
"recid": "bknz"
}
}
}]
}

Related

How can I convert Java List Object to Json with this format? (see body)

anyone know how can I convert this Java List Object to Json?
List<SampleObject> sample = new ArrayList<SampleObject>();
to this format (notice that the Json is not an array)
{
"0": {
"firstName": "",
"lastName": "",
},
"1": {
"firstName": "",
"lastName": "",
}
}
Thanks in advance. Hope you can help me :)
Convert your List to Map, where your key would be an Integer representing 0-based index in your list. After that convert your map to JSON by any standard way and you will get your format. To see how to serialize your Map (or any class) to JSON see this question: How to serialise a POJO to be sent over a Java RSocket?

How to parse JSON with two types of value, one as integer and another as JSON object?

When reading facebook graph api insights response it can have two types of response
"data":{
"name": "page_posts_impressions",
"values": [
{
"value": 10,//integer value
"end_time": "2019-07-29T07:00:00+0000"
}
]
}
here inside values, value has integer value but in another case
"data":{
"name": "page_posts_impressions",
"values": [
{
"value": { "post":10,
"tab":1
}//json object value
"end_time": "2019-07-29T07:00:00+0000"
}
]
}
here value has json object value, how can I parse these king of json object ?
I believe you are going to parse this JSON to java POJO. Since values is Array of Objects i will suggest to parse that into JsonNode, which is
List<JsonNode> values;
Advantage's in this approach is JsonNode has couple of method to find whether it is Integer or JsonObject
isInt()
public boolean isInt()
isObject
public final boolean isObject()

Using GSON to parse Json into a JAVA Object where the Json Elements may vary

I am trying to parse a JSON .txt file into a JAVA object using GSON. The JSON file has the following structure:
{
"event0" : {
"a" : "abc",
"b" : "def"
},
"event1" : {
"a" : "ghi",
"b" : "jkl",
"c" : "mno"
}
}
I have read the text file into a String called dataStr. I want to use the fromJson method to capture the events into the following JAVA class:
public class Event {
private String a;
private String b;
private String c;
public Event() {}
}
The problem is that the JSON might have one extra field "c" in some of the elements. I want to parse all the events into Event class objects, and for the cases where there is no "c" field, I want to make it null or zero in my object. It is not known beforehand which of the elements will have the "c" field.
Specifically, I was not able to figure out how to handle one extra field in some of the JSON elements. I want to do something along the lines of:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
But I am stuck with first, how to iterate over the events in the Json file, and secondly, how to handle some occasional missing fields into the same Event object. I would really appreciate a kick in the right direction. Thank you all.
I am fairly new to JSON parsing, and might have missed something in the following answers:
Using Gson to convert Json into Java Object
Mapping JSON into POJO using Gson
Using gson to parse json to java object
Parse JSON into a java object
How to parse a json file into a java POJO class using GSON
I'm not sure if I understood your question right. As per my understanding, you are trying to convert a json object with an extra field which is not available in the java class. Frankly, I don't understand why you want that or if it's possible to start with. You can have a workaround by converting the json to Map.
Map map = gson.fromJson(jsonString, Map.class);
Gson automatically do that for you.
So, if you have a class "Alpha" with 3 fields ("a", "b" and "c") and you try to work on a json object that has 2 fields with names that match with Alpha's "a" and "b", Gson will fill "a" and "b" with json file's value and "c" will automatically set as null.
So, in your case, if you write this:
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
And in your json there are events with only 2 fields (that match with any Event's class fields) and events with all fields set, you will get a list of Events with no errors. Maybe you'll get some fields null, but the code will work.
I hope to be helpful! Ask for further informations, if you want to!
EDIT
Note that your json file has not to be .txt but .json instead!
First I believe your JSON should look like this:
{
"events": [
{
"name": "event0",
"a": "abc",
"b": "def"
},
{
"name": "event1",
"a": "abc",
"b": "def",
"c": "mno"
}
]
}
This will need two classes for your model:
public List<Event> events = null;
public class Event {
public String name;
public String a;
public String b;
public String c;
}
And then then with GSON
Events events = gson.fromJson(jsonData, Events.class);
Also I recommend to always use an online validator for JSON so you are sure your JSON structure is correct before coding against it.
https://jsonlint.com/
Or for formate the JSON:
http://jsonprettyprint.com/
Also this website can create the Java classes for you from either a JSON Schema or by using an example file.
http://www.jsonschema2pojo.org/
Try the below code snippet:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, new TypeToken<ArrayList<Event>>(){}.getType());
In the source code of Gson has a very clear explain

Deserialize nested JSON array in Java with Gson

Something like this. http://jsonlint.com/ says it is valid. Json inside {} simplified for this example.
[[0,{"ok":true},[]],[1,{"ok":false},[]]]
Or with indents:
[
[0, {
"ok": true
},
[]
],
[1, {
"ok": false
},
[]
]
]
This is class for object JSONClass.
public class JSONClass {
boolean ok;
}
If I got it right, this JSON string is array of arrays, latter containing some ID, actual JSON data and empty array. How could I deserialize that?
This doesn't work. I also tried making class with subclasses, didn't work out.
JSONClass[] t = g.fromJson(json, JSONClass[].class);
Well, you have an array of arrays here. Gson will let you convert the JSON objects themselves into the class you want - but you'll have to call gson.fromJson() on each of them separately.
Given String json containing your json, something like this should work:
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
JsonArray jsonArray = jsonParser.parse(json).getAsJsonArray();
for (JsonElement e: jsonArray) {
JSONClass o = gson.fromJson(e.getAsJsonArray().get(1), JSONClass.class);
}
Essentially, the JsonParser will convert your text into a JsonElement, which is the Gson base class for Json arrays and objects. We can iterate over the elements of the JsonArray which we parsed our text into, which in turn is another array of the format [id, object] - and for each element, take the object portion, and deserialize that into a POJO.

Retrieve a JsonArray that is nested in a changing JSON structure/hierarchy with GSON

I have a situation where I want to retrieve an array from JSON output. The array and its respective members never change. However, the hierarchy of the JSON output that contains the array does change periodically (beyond my control). I am struggling to figure out how to reliably extract the array without knowing the structure of the JSON hierarchy.
Example:
In JSON output #1 we have a bunch of objects with a sailors array nested snuggly in between:
{
"eat": "grub",
"drink": "rum",
"sailors": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Anna",
"lastName": "Smith"
},
{
"firstName": "Peter",
"lastName": "Jones"
}
]
}
In JSON output #2 we have the same sailors array but its located in a different part of the hierarchy:
{
"eat": "grub",
"drink": "rum",
"boats": [
{
"name": "blackpearl"
},
{
"name": "batavia",
"crew": [
{
"name": "captain"
},
{
"name": "deckswab",
"anotherObject": {
"sailors": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Anna",
"lastName": "Smith"
},
{
"firstName": "Peter",
"lastName": "Jones"
}
]
}
}
]
}
]
}
In both cases I want to end up with a Gson JsonArray of the sailors array.
JsonParser parser = new JsonParser();
JsonObject root = parser.parse(json).getAsJsonObject();
JsonArray sailors = root.get("sailors").getAsJsonArray();
The above code works fine for the JSON #1 output. I know that I can rewrite it for JSON output #2 by stringing together a bunch of get and getAsJsonObject/Array methods..
However, Iā€™m not sure how to adapt it so that it will always find the array no matter where it is located in the hierarchy without have to re-write the code each time. This is important for me since the JSON output will likely change again the future and I would like my code to be a little bit more durable so that I do not have to re-write or update it whenever the JSON hierarchy changes again.
Please help!
You may want to use recursion and do this manually (using org.json). You may also use Gson or Jackson to read the tree from the JSON string.
You should have a getSailorsArray(String json) method that returns an array of all sailors.
To do this recursively, create methods to read a JSONArray, read a JSONObject and read a value. Each method will accept an object as argument. Check if the type of object is a JSONArray or a JSONObject or a value and call the appropriate recursive method. If it is an array, you may call the getJsonObject method in loop.
Put in your logic to check for the sailors key, and return the array when you encounter it. There, you have it!

Categories