Get data from JSON file in Java [duplicate] - java

This question already has answers here:
How to parse JSON in Java
(36 answers)
How to read all keys in Json without specifying keyname using java
(2 answers)
Closed 1 year ago.
I would like to read the data from the JSON file, but not only the values but also the fields in this file, i.e. "_id", "name", "surname" etc. For example, I have a file like the one below and the problem is that the files will contain different data and it is not one and the same the file itself so the fields will change and not be the same all the time.
[
{
"_id": 1,
"name": "Adam",
"surname": "Smith",
"course": "IT",
"grades": [
{
"maths": 4,
"physics": 4,
"programming": 5
},
{
"maths": 3,
"physics": 5,
"programming": 4
}
]
},
{
"_id": 2,
"name": "Robert",
"surname": "Brown",
"course": "IT",
"grades": [
{
"maths": 5,
"physics": 5,
"angielski": 5
},
{
"maths": 4,
"physics": 4,
"programming": 4
}
]
}
]
I thought about parsing the file into a string and reading it character by character, but that would be time consuming. And here is my question, how to read not only values but also fields in a JSON file.

I think you want to iterate over all Objects/Arrays in this json.
If you are fine using a library, below one will be helpful
Maven:
<dependency>
<groupId>org.json</groupId>
<artifactId>org.json</artifactId>
<version>chargebee-1.0</version>
</dependency>
This is a sample code for reading your string
import java.io.IOException;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Test {
public static void main(String[] args) throws IOException, JSONException {
String json_str = "[{\r\n" +
" \"_id\": 1,\r\n" +
" \"name\": \"Adam\",\r\n" +
" \"surname\": \"Smith\",\r\n" +
" \"course\": \"IT\",\r\n" +
" \"grades\": [\r\n" +
" {\r\n" +
" \"maths\": 4,\r\n" +
" \"physics\": 4,\r\n" +
" \"programming\": 5\r\n" +
" },\r\n" +
" {\r\n" +
" \"maths\": 3,\r\n" +
" \"physics\": 5,\r\n" +
" \"programming\": 4\r\n" +
" }]\r\n" +
" },{\r\n" +
" \"_id\": 2,\r\n" +
" \"name\": \"Robert\",\r\n" +
" \"surname\": \"Brown\",\r\n" +
" \"course\": \"IT\",\r\n" +
" \"grades\": [\r\n" +
" {\r\n" +
" \"maths\": 5,\r\n" +
" \"physics\": 5,\r\n" +
" \"angielski\": 5\r\n" +
" },\r\n" +
" {\r\n" +
" \"maths\": 4,\r\n" +
" \"physics\": 4,\r\n" +
" \"programming\": 4\r\n" +
" }]\r\n" +
"}]";
JSONArray jsonArray = new JSONArray(json_str);
int length = jsonArray.length();
for(int i=0; i<length; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
//this will give 1st level keys - "surname,name,course,_id,grades"
String key = keys.next();
if (jsonObject.get(key) instanceof JSONObject) {
//build either a recursive function or required logic to iterate over inner json objects similar to this
} else if (jsonObject.get(key) instanceof JSONArray) {
//build either a recursive function or required logic to iterate over inner json arrays similar to this
} else {
/* Output:
key is = surname ==> value is = Smith
key is = name ==> value is = Adam
key is = course ==> value is = IT
key is = _id ==> value is = 1
key is = surname ==> value is = Brown
key is = name ==> value is = Robert
key is = course ==> value is = IT
key is = _id ==> value is = 2
*/
System.out.println("key is = "+key+" ==> value is = "+jsonObject.get(key));
}
}
}
}
}

Related

how to iterate json and convert into following json format in JAVA

How to iterate json in java. I wanted iterate elements inside payload, grab the first level and second level key and array value. I have converted the same in python. I'm new to java and wanted convert in java. Any help would be appreciated.
Python Code:
import os
import sys
import json
import datetime
def lambda_handler(event, context):
indata = event['payload']
outputDictionary = []
for i in indata:
for j in indata[i]:
for k in indata[i][j]:
outputDictionary.append(dict(source = i,code=j,version=k))
return outputDictionary
Input :
{
"payload": {
"gtl": {
"435185": [
"2019-11-27T14:34:32.368197Z"
]
},
"ptl": {
"A0947863": [
"2019-11-27T14:34:32.368197Z"
]
},
"mtl": {
"A0947863": [
"2019-11-27T14:34:32.368197Z",
"2021-04-27T06:13:12.841968Z"
]
}
}
}
Expected Output
[
{
"source": "gtl",
"code": "435185",
"version": "2019-11-27T14:34:32.368197Z"
},
{
"source": "ptl",
"code": "A0947863",
"version": "2019-11-27T14:34:32.368197Z"
},
{
"source": "mtl",
"code": "A0947863",
"version": "2019-11-27T14:34:32.368197Z"
},
{
"source": "mtl",
"code": "A0947863",
"version": "2021-04-27T06:13:12.841968Z"
}
]
SOLVED IN JAVA:
Java CODE:
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ParseJson {
public static void main(String[] args) {
String inputJson = "{\r\n" +
" \"payload\": {\r\n" +
" \"gtl\": {\r\n" +
" \"435185\": [\r\n" +
" \"2019-11-27T14:34:32.368197Z\"\r\n" +
" ]\r\n" +
" },\r\n" +
" \"ptl\": {\r\n" +
" \"A0947863\": [\r\n" +
" \"2019-11-27T14:34:32.368197Z\"\r\n" +
" ]\r\n" +
" },\r\n" +
" \"mtl\": {\r\n" +
" \"A0947863\": [\r\n" +
" \"2019-11-27T14:34:32.368197Z\",\r\n" +
" \"2021-04-27T06:13:12.841968Z\"\r\n" +
" ]\r\n" +
" }\r\n" +
" }\r\n" +
"}";
final JSONObject inputJSONOBject = new JSONObject(inputJson);
JSONObject jsonChildObject = (JSONObject)inputJSONOBject.get("payload");
Iterator iterator = jsonChildObject.keys();
while (iterator.hasNext()) {
String key = null;
while(iterator.hasNext()){
String source = (String)iterator.next();
JSONObject codeChildObject = jsonChildObject.getJSONObject(source);
Iterator iterator2 = codeChildObject.keys();
while(iterator2.hasNext()){
String code = (String)iterator2.next();
org.json.JSONArray jsonArray = codeChildObject.getJSONArray(code);
for(int i=0;i<jsonArray.length();i++){
System.out.println("Source:" + source);
System.out.println("CODE:" + code);
System.out.println("Version: "+jsonArray.get(i));
}
}
}
}
}
//System.out.println(inputJSONOBject);
}
You have done everything right except for that extra loop for the first iterator. Following is the complete working solution.
class ParseJson {
public static void main(String[] args) throws Exception {
String inputJson = "{\r\n" +
" \"payload\": {\r\n" +
" \"gtl\": {\r\n" +
" \"435185\": [\r\n" +
" \"2019-11-27T14:34:32.368197Z\"\r\n" +
" ]\r\n" +
" },\r\n" +
" \"ptl\": {\r\n" +
" \"A0947863\": [\r\n" +
" \"2019-11-27T14:34:32.368197Z\"\r\n" +
" ]\r\n" +
" },\r\n" +
" \"mtl\": {\r\n" +
" \"A0947863\": [\r\n" +
" \"2019-11-27T14:34:32.368197Z\",\r\n" +
" \"2021-04-27T06:13:12.841968Z\"\r\n" +
" ]\r\n" +
" }\r\n" +
" }\r\n" +
"}";
JSONArray output = convert(inputJson);
System.out.println(output.toString(5));
}
private static JSONArray convert(String inputJson) throws Exception {
final JSONObject inputJSONOBject = new JSONObject(inputJson);
JSONObject jsonChildObject = (JSONObject) inputJSONOBject.get("payload");
JSONArray outputArray = new JSONArray();
Iterator payloadIterator = jsonChildObject.keys();//gtl,ptl,mtl
while (payloadIterator.hasNext()) {
String source = (String) payloadIterator.next(); //gtl
JSONObject codeChildObject = jsonChildObject.getJSONObject(source);
Iterator codeIterator = codeChildObject.keys();//123, 456
while (codeIterator.hasNext()) {
String code = (String) codeIterator.next();//123
org.json.JSONArray jsonArray = codeChildObject.getJSONArray(code);// t1,t2,t3
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = new JSONObject();
object.put("source", source);
object.put("code", code);
object.put("version", jsonArray.get(i)); //t1
outputArray.put(object);
}
}
}
return outputArray;
}
}

Looping through SerenityRest Response in JAVA

I am trying to get a count of all models from the cars object, which is part of a SerenityRest response.
Response response = SerenityRest.rest()
.contentType("application/json")
.when()
.get("/api/");
if (response.statusCode() == 200) {
int numUniqueModels = response.body().path("cars.size()"); // 3
}
Response:
"cars": {
"Acura": [
"ILX",
"MDX",
"TLX"
],
"Audi": [
"A3",
"A4",
"A6",
"A7"
],
"BMW": [
"x",
"y"
]
}
For example,
response.body().path("cars.size()") = 3,
but i need the sum of cars.Acura.size() + cars.Audi.size() + cars.BMW.size() to get all models. However, i don't know if the exact names Acura, Audi or BMW will exist in the response, since vehicles may change dynamically. To solve this, i will need to do some kind of a loop, where:
sum = 0;
for (int i = 0; i < response.body().path("cars.size()"); i++) {
sum += response.body().path("cars.[i].size()");
}
The sum should give a total number of car models = 9.
The problem is that this syntax: path("cars.[i].size()") is not correct. What is the correct call?
If you want to make complex request with rest-assured you have to follow the synthax described here groovy gpath as mentionned here rest-assured doc:
Note that the JsonPath implementation uses Groovy's GPath syntax and is not to be confused with Jayway's JsonPath implementation.
So you have to play with some groovy synthax:
int total = JsonPath.from("{ "
+ " \"cars\": {\n"
+ " \"Acura\": [\n"
+ " \"ILX\",\n"
+ " \"MDX\",\n"
+ " \"TLX\"\n"
+ " ],\n"
+ " \"Audi\": [\n"
+ " \"A3\",\n"
+ " \"A4\",\n"
+ " \"A6\",\n"
+ " \"A7\"\n"
+ " ],\n"
+ " \"BMW\": [\n"
+ " \"x\",\n"
+ " \"y\"\n"
+ " ]\n"
+ " }"
+ "}")
.getInt("cars.collect { it.value.size() }.sum()")
So this expression should make the job cars.collect { it.value.size() }.sum(). The collect method is like a map method in functional programming. So you map the collection cars HashMap with the size() of its values and you collect the sum()!
Edit
So you just have to do:
Response response = SerenityRest.rest()
.contentType("application/json")
.when()
.get("/api/");
if (response.statusCode() == 200) {
int numUniqueModels = response.body().path("cars.collect { it.value.size() }.sum()"); // 9
}

How to loop through json array of json object in java

I am trying to loop through the json file and find the value of particular json object.
Here is my sample json:
{
"diagram":[
{"size":{"width":30,"height":20},"color":"blue","id":1},
{"color":"red","id":2},
{"size:{"height":30}", "id":3}
]
}
What i want to do is to iterate through the file and find the "id" element.
I used below code to convert the JsonFile into JsonObject and to get the value of "diagram" object
JSONArray jsonArray = new JSONArray();
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("D:/test.json"));
JSONObject jsonObj = (JSONObject) obj;
for(Iterator iterator = jsonObj.keySet().iterator(); iterator.hasNext();) {
String diagramKey = (String) iterator.next();
jsonArray.put(jsonObj.get(diagramKey));
}
With the above code i was able to get the value of diagram object and i have put that into the jsonArray
When i am trying to print the array object i am getting output as
[[
{"size":{"width":30,"height":20},"color":"blue","id":1},
{"color":"red","id":2},
{"size:{"height":30}", "id":3}
]]
and the jsonArray length is coming as 1.
How to loop through the above jsonArray and find the id of each individual element
Verify your JSON too and check below code.
public class MyTest {
public static void main(String[] args) throws JSONException {
String str = "{\r\n" +
" \"diagram\": [{\r\n" +
" \"size\": {\r\n" +
" \"width\": 30,\r\n" +
" \"height\": 20\r\n" +
" },\r\n" +
" \"color\": \"blue\",\r\n" +
" \"id\": 1\r\n" +
" },\r\n" +
" {\r\n" +
" \"color\": \"red\",\r\n" +
" \"id\": 2\r\n" +
" },\r\n" +
" {\r\n" +
" \"size\": {\r\n" +
" \"height\": 30\r\n" +
" },\r\n" +
" \"id\": 3\r\n" +
" }\r\n" +
" ]\r\n" +
"}";
JSONObject jo = new JSONObject(str);
final JSONArray geodata = jo.getJSONArray("diagram");
int arrLength = geodata.length();
for(int i = 0; i< arrLength;i++) {
jo = geodata.getJSONObject(i);
System.out.println(jo.get("id"));
}
}
}
Your json format is wrong.
You can always validate your json format using tools online
https://jsonformatter.curiousconcept.com/
https://jsonformatter.org/
Correct json format
{
"diagram":[
{
"size":{
"width":30,
"height":20
},
"color":"blue",
"id":1
},
{
"color":"red",
"id":2
},
{
"size":{
"height":30
},
"id":3
}
]
}

How to Traverse in the nested JSON data using java

I'm trying to get the values of Alpha, Beta and Gamma from a nested JSON data file.
I'm trying get the Alpha value using something like this
Object o = new JSONParser().parse(new FileReader(newFile("C:\\Users\\abc\\Documents\\file.json")));
JSONObject jo = (JSONObject) o;
JSONArray resultCode = (JSONArray) jo.get("mkDetails");
JSONObject x = (JSONObject) resultCode.get(0);
x.get("Alpha").toString()
This is the JSON:
{
"metadata": {
"offset": 0,
"psize": 10
},
"svc": [
{
"mNumber": "225",
"markIp": {
"Name": "Ant",
"eDate": "3006-08-01",
"cDate": "9999-12-31"
},
"mkDetails": [
{
"Alpha": "D",
"Beta": "S"
}
],
"mNetDetails": [
{
"Gaama": "213",
"mkTypeCode": "23"
}
]
}
],
"serviceFault": {
"faultType": null,
"faultCode": null,
"message": null
}
}
Here is a possible solution. I'm using Gson lib from google. You can import via maven.
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Here is the code that parses your JSON.
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public static void parseJson (){
String thisJson ="{\r\n" +
" \"metadata\": {\r\n" +
" \"offset\": 0,\r\n" +
" \"psize\": 10\r\n" +
" },\r\n" +
" \"svc\": [\r\n" +
" {\r\n" +
" \"mNumber\": \"225\",\r\n" +
" \"markIp\": {\r\n" +
" \"Name\": \"Ant\",\r\n" +
" \"eDate\": \"3006-08-01\",\r\n" +
" \"cDate\": \"9999-12-31\"\r\n" +
" },\r\n" +
" \"mkDetails\": [\r\n" +
" {\r\n" +
" \"Alpha\": \"D\",\r\n" +
" \"Beta\": \"S\"\r\n" +
" }\r\n" +
" ],\r\n" +
" \"mNetDetails\": [\r\n" +
" {\r\n" +
" \"Gaama\": \"213\",\r\n" +
" \"mkTypeCode\": \"23\"\r\n" +
" }\r\n" +
" ]\r\n" +
" }\r\n" +
" ],\r\n" +
" \"serviceFault\": {\r\n" +
" \"faultType\": null,\r\n" +
" \"faultCode\": null,\r\n" +
" \"message\": null\r\n" +
" }\r\n" +
"}";
Gson gson = new Gson();
JsonElement jelement = new JsonParser().parse(thisJson);
JsonObject jobject = jelement.getAsJsonObject();
JsonArray jarray = jobject.getAsJsonArray("svc");
jobject = jarray.get(0).getAsJsonObject();
JsonArray netDetailsArr = jobject.getAsJsonArray("mNetDetails");
JsonArray mkDetailsArr = jobject.getAsJsonArray("mkDetails");
jobject = netDetailsArr.get(0).getAsJsonObject();
String gamma = jobject.get("Gaama").getAsString();
System.out.println("gamma==>" + gamma);
jobject = mkDetailsArr.get(0).getAsJsonObject();
String alpha = jobject.get("Alpha").getAsString();
String beta = jobject.get("Beta").getAsString();
System.out.println("alpha ==>" + alpha);
System.out.println("beta ===>"+ beta);
}
console output :
gamma==>213
alpha ==>D
beta ===>S
You can’t just do jo.get("mkDetails"), because jo has no key mkDetails. You have to traverse every level of the tree yourself:
JSONObject root = ...;
JSONArray svc = (JSONArray) root.get("svc");
JSONObject svc0 = (JSONObject) svc.get(0);
JSONObject mkDetails = (JSONObject) svc0.get("mkDetails");
JSONObject mNetDetails = (JSONObject) svc0.get("mNetDetails");
String alpha = (String) mkDetails.get("Alpha");
String beta = (String) mkDetails.get("Beta");
String gamma = (String) mNetDetails.get("Gamma");

Parsing a list of different JSON objects with Gson

How to parse below stream of Json objects?
There are example for array parsing but not stream of json objects. Only the first object is different other than that every other object is similar.
Its not array but stream of json objects.
[{
"code": 200,
"request_id": "52d868df5ada23e5f289320f",
"ok": true,
"payload_meta": {
"original_size": 1837,
"size": 1837
}
},{
"id": "4fb56d7f273fb7ebfe22783f",
"duration": "6:49",
"duration_seconds": 409,
"size_bytes": 16396948
}{
"id": "4fb56d7f273fb7ebfe227841",
"duration": "3:42",
"duration_seconds": 222,
"size_bytes": 8904980
}{
"id": "4fb56d7f273fb7ebfe227846",
"duration": "4:06",
"duration_seconds": 246,
"size_bytes": 9843339
}]
And also how to notify after parsing one object successfully instead of waiting whole stream to complete.
I made no assumptions on the kind of object you are trying to deserialize. So I named Class1 and Class2 the two kind of objects and they have no relationship. I declared them as inner static classes to make compat the example, but you can move Class1 and Class2 to separate files. I paste you a ready to run code so that you can try it on your own.
package stackoverflow.questions.q23556772;
import java.util.*;
import com.google.gson.*;
public class Q23556772 {
public static class Class1 {
String code;
String request_id;
Boolean ok;
HashMap<String, Integer> payload_meta;
#Override
public String toString() {
return "Class1 [code=" + code + ", request_id=" + request_id + ", ok=" + ok + ", payload_meta=" + payload_meta + "]";
}
}
public static class Class2 {
String id;
String duration;
Integer duration_seconds;
Integer size_bytes;
#Override
public String toString() {
return "Class2 [id=" + id + ", duration=" + duration + ", duration_seconds=" + duration_seconds + ", size_bytes=" + size_bytes + "]";
}
}
public static void main(String[] args) {
String json =
"[{ "+
" \"code\": 200, "+
" \"request_id\": \"52d868df5ada23e5f289320f\", "+
" \"ok\": true, "+
" \"payload_meta\": { "+
" \"original_size\": 1837, "+
" \"size\": 1837 "+
" } "+
"},{ "+
" \"id\": \"4fb56d7f273fb7ebfe22783f\", "+
" \"duration\": \"6:49\", "+
" \"duration_seconds\": 409, "+
" \"size_bytes\": 16396948 "+
"},{ "+
" \"id\": \"4fb56d7f273fb7ebfe227841\", "+
" \"duration\": \"3:42\", "+
" \"duration_seconds\": 222, "+
" \"size_bytes\": 8904980 "+
"},{ "+
" \"id\": \"4fb56d7f273fb7ebfe227846\", "+
" \"duration\": \"4:06\", "+
" \"duration_seconds\": 246, "+
" \"size_bytes\": 9843339 "+
"}] ";
ArrayList<Object> result = new ArrayList<>();
Gson g = new Gson();
JsonArray e = new JsonParser().parse(json).getAsJsonArray();
for(int i = 0; i < e.size(); i++){
JsonObject o = e.get(i).getAsJsonObject();
if (o.get("code") != null)
result.add(g.fromJson(o, Class1.class));
else if (o.get("id") != null)
result.add(g.fromJson(o, Class2.class));
else result.add(g.fromJson(o, Object.class));
}
for(Object resultObject: result)
System.out.println(resultObject.toString());
}
}
As you can see, I use a combination of JsonParser and Gson methods. I use the parser to peek inside the "stream" and to decide what is the correct class to use, then I use standard Gson deserialization to do the work. This code could be adapted into a custom TypeAdapter, but probably it makes the code "complex" beyond your real needs.
Final note: I edited your JSON since it was incorrect.

Categories

Resources