How to get the name of array in JSON using Java - java

Given a Json object or a Json array that contains a Json array inside, I need to return the name of the array itself, without specifying the value inside the array.
In the code, given JSON, and Jsonpath from user, I need to return the name of the array.
Example- given this JSON:
{
"Contract details": [
{
"type": "regular",
"Details": [
{
"Name": "Josh",
"Country": "USA"
},
{
"Name": "Jake",
"Country": "UK"
}
]
}
]
}
I want to be able to find if the array block "Details" exists within the JSON.
Right now, in order to verify its existence, the user need to specify the full Jsonpath to a value inside the block, which is time consuming, like this:
$.Contract details[0].Details[?(#.Name== 'Josh')]
This is where I get the jsonPath result in the code, and where I want to verify afterwards the existence of the array object.
//json and jsonPath are given strings
Object jsonObjectType = JsonPath.read(json, jsonPath);
I want to verify that "Details" array block exists, maybe by a short effective JsonPath, or some other way in the code, given json as string.

Related

Rest assured and Java: how to get wanted JSON object/body?

Lets assume I have a GET request that returns something like the following:
[
{
"id": 1,
"name": "Mark"
},
{
"id": 2,
"name": "Steve"
},
{
"id": 3,
"name": "Bill"
}
]
How can I return the wanted object from a List? or something that contains maybe this JSON as a String or what is the correct approach to get only one of the items from the response for example lets say i need to get Bills info only so i want to parse that JSON to get only this:
{
"id": 3,
"name": "Bill"
}
And no, I do not want to do this parsing in the GET request URL. I need to be able to get it from the list of everything that the GET request returns.
"$[2]"
In JsonPath, $ represents the anonymous root of the queried JSON, for cases like this one when you need to refer to it directly instead of stuff like "stuff.things[8]"
In this case, the array you're trying to analyze is the anonymous root, so you refer to it as $. Then you want the element at index 2 of this array, so it's $[2]
I did another solution that actually fits exactly for my needs. I deserialized the JSON response into a List of POJO classes that the JSON body corresponds like this:
List<MyEntity> myList = new ArrayList<>();
myList = given().
contentType(ContentType.JSON).
when().
get(getURL).
then().
extract().
body().
jsonPath().
getList(".", MyEntity.class);
This way I get a List of the initialized MyEntity classes and I can just do anything I need to, for example I just modify the values like this:
myList.get(0).setName("newName");
Then I can just send them back with a POST/PUT calls or something like that. Works like a charm!

How to/best practice on how to differentiate between serialised objects stored within JSON format?

Suppose that I serialise two different objects and save them to a directory.
Problem: Upon application start up, parsing the JSON files are not a problem - since GSON is employed, I can write my own serialisers and deserialisers for both of the JSON files for their respective objects to be constructed.
But the problem is, how can I differentiate between the numerous JSON files in terms of what they store within them, so I can apply the correct deserialiser to it.
Thank you, best.
Consider standardizing your JSON structure to include document type. You can even store the target object type in that field. Good practice is to include document version number as well. Example below shows two different versions of the 'account' document and a transaction document. All three can be stored in, say, the same Couchbase bucket. The way to differentiate between different documents would be to look at the "doc_type" field and the document version (if required). From the GSON serializer selection standpoint, you can look at at the "doc_type" in a switch/if-else statement or store the target object type in place of "account" or "transaction" and then, at the expense of performance, dynamically parse JSON to POJO.
{
"doc_type": "account",
"doc_ver": 1,
"content": {
"accnt_no": "12321645645484",
"name": "Name or alias",
"email": "Email address",
"password": "Password in raw format",
"exp_date": "06/10/2017"
}
}
{
"doc_type": "account",
"doc_ver": 2,
"content": {
"accnt_no": "12321645645484",
"name": "customer name",
"email": "customer email",
"password": "pass",
"timezone": "customer timezone",
"ip": "IP address",
"spoken_languages": [ "EN", "RU" ],
"exp_date": "06/10/2017"
}
}
{
"doc_type": "transaction",
"doc_ver": 1,
"content": {
"accnt_no": "12321645645484",
"tran_date": "06/04/2017",
"tran_time": "09:15:84.953"
}
}
Hope this helps.
I think that the best way is parse JSON to a HashMap<String, Object> with multiple level. GSON will parse your JSON to HashMap with key is object name and value is an object (This object will belong to 3 type: HashMap for a object in JSON, List for an array in JSON and String for a string in JSON). To using this HashMap you need to iterate through the HashMap using a recursive method.

Mapping JSON Array to Java POJO

How would i map this JSON to an object?
{"d":"[{\"Key\":\"3\",\"ExternalKey\":\"143234A\",\"Name\":\"cup of juice\",\"Litres\":\"2 litres\",\"Date\":\"2016-10-06T08:32:27\",\"Capacity\":5.4900,\"CapacityType\":\"%\"}, {\"Key\":\"3\",\"ExternalKey\":\"143234A\",\"Name\":\"cup of milk\",\"Litres\":\"2.4 litres\",\"Date\":\"2016-10-06T08:32:27\",\"Capacity\":1667.6100,\"CapacityType\":\"M\"}]"}
I've tried using a HashMap but it just puts "d" as the string and the rest as a String object with one element
This is an extremely common problem known as data marshaling. In java, Jackson is the general best solution. Read this tutorial: http://wiki.fasterxml.com/JacksonInFiveMinutes
Your Json string has some extra " characters.
This is the final json:
{
"d": [
{
"Key": "3",
"ExternalKey": "143234A",
"Name": "cup of juice",
"Litres": "2 litres",
"Date": "2016-10-06T08:32:27",
"Capacity": 5.49,
"CapacityType": "%"
},
{
"Key": "3",
"ExternalKey": "143234A",
"Name": "cup of milk",
"Litres": "2.4 litres",
"Date": "2016-10-06T08:32:27",
"Capacity": 1667.61,
"CapacityType": "M"
}
]
}
Now you can copy the json and paste it here to get the pojo.
There are n numbers of libraries available for parsing the JSON and convert into in java classes.
Some of the examples are,
GSON
Jackson
Logan Square
Moshi, etc
You need to create a java class which map with your JSON Response and need to change your pojo according to parsing library.
For Example,
Using Logan Square you must annotate your POJO class to #JsonObject and all properties must be annotated with #JsonField.
Now, you can parse your json using method
...
LoganSquare.parse(jsonString, pojoClassName);
...
Hopefully this will help you.
Cheers
if i substring out the "d" key and map it as a JSON Array it works, that'll have to be the solution for now...

JSON Conversion Object having same name as Array in separate record

I am trying to parse the below JSON using retrofit. Here JSON object is having same name as JSON Array. Is there a way to correctly create pojo's
Here button is an Object in first record whereas in the second record it is an Array.
Is this valid as per JSON specification.
{
"Single": [{
"button": {
"target": "https://m.jjj.com",
"title": "Shop Now"
},
"description": "W1",
"image": "http://dojo.scene11.com/is/image/anf/anf-US-20150629",
"title": "Sports at $25"
}, {
"button": [{
"target": "https://m.abz.com",
"title": "Shop Now"
}],
"description": "Good",
"image": "http://axys.com.m/is/image/brands",
"title": "gebra "
}]
}
This is a valid JSON as per JSON specifications, but as we know an Array must have same type of values, you are violating that logic. So when you would be trying to directly map this JSON to the Java Object, it might give an exception, but in case you have written a custom parser, you might be able to use it properly.
Yes, this is valid if you are using proper function to parse your json. There can be json object and json array of same 'name'.
But there should not be two objects of same name, or two arrays of same name. Even this will be valid json having two object(or array) of same name, but you will be able to get only one json object(or array) while parsing your json.

Convert nested arbitrary JSON to CSV in Java

This question has been asked many times but I couldn't find the answer that fixes my issue.
I'm trying to convert nested JSON format to CSV format like this :
The JSON structure is arbitrary and could be anything, nested or not.
I'm not suppose to know it, it's a database answer and I need to export this JSON answer into CSV file.
Here is an example
Input :
{
"_id": 1,
"name": "Aurelia Menendez",
"scores": [
{
"type": "exam",
"score": 60.06045071030959
},
{
"type": "quiz",
"score": 52.79790691903873
},
{
"type": "homework",
"score": 71.76133439165544
}
]
}
The output I'm looking for :
_id,name,scores.type,scores.score,scores.type,scores.score,scores.type,scores.score
1,Aurelia Menendez,exam,60.06...,quiz,52.79...,homework,71.76..
This is an example, it could be any other JSON document.
The idea here is to use dot notation in the CSV column name.
I've already used CDL but the output is not what I want :
_id scores name
1 "[{score:60.06045071030959,type:exam},{score:52.79790691903873,type:quiz},{score:71.76133439165544,type:homework}]" Aurelia Menendez
So how can I convert nested JSON to CSV with dot notation and in a generic way ?
Edits
Deserialisation of the JSON with Jackson :
ObjectMapper mapper=new ObjectMapper();
JsonNode jsonNode=mapper.readValue(new File("C:\\...\\...\...\\test.json"), JsonNode.class);
Ismail
Like you said :
The JSON structure is arbitrary and could be anything, nested or not.
The JSON to CSV conversion can't be generalized as it varies from user to user and also depends specific requirements.
But still there's a library json2flat which tries to achieve it. But it may differ from user's requirement. Still it's worth a try.
For example for the JSON given above:
{
"_id": 1,
"name": "Aurelia Menendez",
"scores": [
{
"type": "exam",
"score": 60.06045071030959
},
{
"type": "quiz",
"score": 52.79790691903873
},
{
"type": "homework",
"score": 71.76133439165544
}
]
}
can be interpreted as follows :
/_id,/name,/scores/type,/scores/score
1,"Aurelia Menendez","exam",60.06045071030959
1,"Aurelia Menendez","quiz",52.79790691903873
1,"Aurelia Menendez","homework",71.76133439165544
Converting JSON to XLS/CSV in Java has what you are looking for.
Basically, you need to use org.json.CDL to convert from JSON to CSV format
Comments are not convenient place to post longs answers, so I post my answer here.
Analyze your JSON and all possible JSON structures you can get from your database. It should be a limited number of JSON forms.
As you have analyzed your JSON structure build a class/class hierarchy, that fully reflects this structure.
Use JSON serializer/deserializer library at your choice, to deserialize JSON to a java object.
Employ StringBuffer/StringBuilder classes, and iterate over your object information, and build comma delimited (or tab-delimited) strings.
Write strings you have built on the previous stage to the file.
That's it.

Categories