How to parse a flattened Json? - java

I have a requirement to use flattened structure JSON, for example below hierarchical Json:
{
"employees": [
{
"employee1": {
"employeeId": 123,
"name": "ABC",
"type": "permanent",
"address": {
"street": "",
"city": "",
"zipcode": 123456
},
"phoneNumbers": [
123456,
987654
],
"designation": "Manager",
"properties": {
"age": "29 years",
"joiningDate": "17-may-2017",
"salary": "1000 USD"
}
}
},
{
"employee2": {
"employeeId": 123,
"name": "XYZ",
"type": "parttime",
"address": {
"street": "",
"city": "",
"zipcode": 345645
},
"phoneNumbers": [
345332,
675444
],
"designation": "Contractor",
"properties": {
"age": "35 years",
"joiningatDate": "17-june-2015",
"salary": "700 USD"
}
}
}
]
}
**Could be represented as flat structure Json as below(generated this using json-flattener):**
{
"employees[0].employee1.address.zipcode": 123456,
"employees[0].employee1.address.city": "",
"employees[0].employee1.address.street": "",
"employees[0].employee1.name": "ABC",
"employees[0].employee1.employeeId": 123,
"employees[0].employee1.designation": "Manager",
"employees[0].employee1.type": "permanent",
"employees[0].employee1.phoneNumbers[0]": 123456,
"employees[0].employee1.phoneNumbers[1]": 987654,
"employees[0].employee1.properties.joiningDate": "17-may-2017",
"employees[0].employee1.properties.salary": "1000 USD",
"employees[0].employee1.properties.age": "29 years",
"employees[1].employee2.address.zipcode": 345645,
"employees[1].employee2.address.city": "",
"employees[1].employee2.address.street": "",
"employees[1].employee2.name": "XYZ",
"employees[1].employee2.employeeId": 123,
"employees[1].employee2.designation": "Contractor",
"employees[1].employee2.type": "parttime",
"employees[1].employee2.phoneNumbers[0]": 345332,
"employees[1].employee2.phoneNumbers[1]": 675444,
"employees[1].employee2.properties.joiningDate": "17-june-2015",
"employees[1].employee2.properties.salary": "700 USD",
"employees[1].employee2.properties.age": "35 years"
}
My problem is if my service receives flattened Json like above, how to convert it to java domain objects automatically like:
class Employee{
Address address;
Properties property;
}
Does any Java Json parser supports this automatic conversion or i will have to implement own parsing logic splitting the keys based on dot in the keys?
Thanks in Advance.

You can take a look at json-flattener.
It does what you want, and even more.
The usage is simple as this:
String json = "{ \"a\" : { \"b\" : 1, \"c\": null, \"d\": [false, true] }, \"e\": \"f\", \"g\":2.3 }";
String jsonStr = JsonFlattener.flatten(json);
System.out.println(jsonStr);
// Output: {"a.b":1,"a.c":null,"a.d[0]":false,"a.d[1]":true,"e":"f","g":2.3}

Related

How to get json key values by another key value

I have a JSON output like this:
{
"items": [
{
"id": "1",
"name": "Anna",
"values": [
{
"code": "Latin",
"grade": 1
},
{
"code": "Maths",
"grade": 5
}
]
},
{
"id": "2",
"name": "Mark",
"values": [
{
"code": "Latin",
"grade": 5
},
{
"code": "Maths",
"grade": 5
}
]
}
]
}
I need to get field values for "name": "Anna". I am getting RestAssured Response and would like to use my beans to do that, but I can also use jsonPath() or jsonObject(), but I don't know how. I searched many topics but did not find anything.

ArrayList put a field in each map of the list according to the value of another arrayList

I have an arraylist:
{
"response": [
{
"number": "229425941 ",
"CURRENCY": "EUR",
"account": "0026.5501.90.0490520505",
"branch": "0154",
"product": "geia",
"service": "0026.0002.62.0300162968",
"amount": 20000,
"expDate": "2019-09-20",
"bank": "0026",
"name": "A name "
},
{
"number": "229425941 ",
"CURRENCY": "EUR",
"account": "0026.5501.90.0490520505",
"branch": "0154",
"product": "geia",
"service": "0026.0002.62.0300162968",
"amount": 20000,
"expDate": "2019-09-20",
"bank": "0027",
"name": "A name "
},
]
}
and I have a second arraylist which contains details for each bank. The list is this:
"details": [
{
"bankCode": "010",
"bankDescription": "BANK",
},
{
"bankCode": "011",
"bankDescription": "NATIONAL",
},
{
"bankCode": "012",
"bankDescription": "ALPHA",
}
]
}
Now I want to loop through the first list and put the bankDescription field in each object of the list according to the bankCode and the bankDescription of the second list. I made a stream for the first arrayList:
firtsList.stream().forEach(a -> {
a.put();
});
My guess is that somehow to loop through the second list but I don't know an efficient way. My output must be something like this:
{
"response": [
{
"number": "229425941 ",
"CURRENCY": "EUR",
"account": "0026.5501.90.0490520505",
"branch": "0154",
"product": "geia",
"service": "0026.0002.62.0300162968",
"amount": 20000,
"expDate": "2019-09-20",
"bank": "010",
"bankDesc: "BANK"
"name": "A name "
},
{
"number": "229425941 ",
"CURRENCY": "EUR",
"account": "0026.5501.90.0490520505",
"branch": "0154",
"product": "geia",
"service": "0026.0002.62.0300162968",
"amount": 20000,
"expDate": "2019-09-20",
"bank": "011",
"bankDesc: "NATIONAL"
"name": "A name "
},
]
}
secondList.stream().filter(bic -> firstList.stream()
.anyMatch(c -> StringUtils.substring((String) c.get("bankDesc"), 1, 3)
.equals(bic.get("bankCode"))));
Have a model/dto to simplify the process. You can use objectMapper to map Json directly into POJO.
Assuming you disregard all advice and proceed with Json/Map, here's how you can proceed:
//Build a dictionary from the data
Map<String, String> bankCodeToDescriptionMap = secondList.stream().collect(Collectors.toMap(v -> v.get("bankCode"), v -> v.get("bankDescription")));
firstList.stream().forEach(a -> {
a.put("bankDescription", bankCodeToDescriptionMap.get(v.get("bankCode")));
});
Do not iterate over the list for each value. It will be too slow

How i do grouping and transform data in java language

I try to use group by in Collectors.groupingBy in java but i can not get data form that i want.
I want to transform this form data :
[
{
"id": 1,
"name": "A",
"company_id": "01",
"company_name": "Company A",
},
{
"id": 2,
"name": "B",
"company_id": "01",
"company_name": "Company A",
},{
"id": 3,
"name": "C",
"company_id": "02",
"company_name": "Company B",
}
]
to this data form:
[
{
"company_id": "01",
"company_name": "Company A",
"member":[
{
"id": 1,
"name": "A"
},
{
"id": 2,
"name": "B"
}
]
},{
"company_id": "02",
"company_name": "Company B",
"member":[
{
"id": 3,
"name": "C"
}
]
}
]
this form group by company_id.
The way that I would do it:
First I would create pojo objects for both formats, then I would assign each value corresponding ones then I would convert the second object into json as using gson.

How to count by attribute in JSON?

I have the following JSON:
{
"items": [
{
"id": "1",
"name": "John",
"location": {
"town": {
"id": "10"
},
"address": "600 Fake Street",
},
"creation_date": "2010-01-19",
"last_modified_date": "2017-05-18"
},
{
"id": "2",
"name": "Sarah",
"location": {
"town": {
"id": "10"
},
"address": "76 Evergreen Street",
},
"creation_date": "2010-01-19",
"last_modified_date": "2017-05-18"
},
{
"id": "3",
"name": "Hamed",
"location": {
"town": {
"id": "20"
},
"address": "50 East A Street",
},
"creation_date": "2010-01-19",
"last_modified_date": "2017-05-18"
}
]
}
And I need to get something like this, count how many times each townId appears:
[ { "10": 2 }, {"20": 1 }]
I'm trying to find the most eficient way to do this. Any idea?
Most efficient way is to load the String in a StringBuilder and remove all line breaks and white spaces. Then search for index of "town":{"id":" string (town start index) and then search for the end index (String `"}'). Using the 2 indexes you can extract town ids and count them.
No need to deserialize the JSON into POJO objects:) and extract values by xpath from the POJOs.

jsonpath using regular expressions in Talend 5.5

I have this json string:
I want to extract all the ids that are after the node of number:"0","1","2"...etc.
I have succeeded to get a single id by using jsonpath: $.response.data.0.id and got "15124".
but i'm looking for a jsonpath that will extract all the ids in the Json String.
in other words this is the expexted output: 15124,13498,14296,13364,14060,13672.
This is the Json String i have:
{
"response": {
"code": 200,
"msg": "Success",
"data": {
"0": {
"id": "15124",
"name": " yoav (yoavshaki#yahoo.com) - 301519506662355",
"network_id": 1,
"network_type": "Facebook",
"currency": "USD",
"currency_info": {
"prefix": "$",
"postfix": "",
"name": "US Dollars"
},
"timezone": {
"id": 139,
"code": "IST",
"region": "Asia",
"locality": "Jerusalem",
"offset": 3,
"facebook_code": 70
}
},
"1": {
"id": "13498",
"name": "(Not in used) Daniel - 30138444",
"network_id": 1,
"network_type": "Facebook",
"currency": "USD",
"currency_info": {
"prefix": "$",
"postfix": "",
"name": "US Dollars"
},
"timezone": {
"id": 92,
"code": "PST",
"region": "America",
"locality": "Los_Angeles",
"offset": -7,
"facebook_code": 1
}
},
"2": {
"id": "14296",
"name": "Daniel - ComeOn (bingocafe#walla.com - 1375713835981039)",
"network_id": 1,
"network_type": "Facebook",
"currency": "USD",
"currency_info": {
"prefix": "$",
"postfix": "",
"name": "US Dollars"
},
"timezone": {
"id": 92,
"code": "PST",
"region": "America",
"locality": "Los_Angeles",
"offset": -7,
"facebook_code": 1
}
},
"3": {
"id": "13364",
"name": "Erez - 116060088528093",
"network_id": 1,
"network_type": "Facebook",
"currency": "USD",
"currency_info": {
"prefix": "$",
"postfix": "",
"name": "US Dollars"
},
"timezone": {
"id": 92,
"code": "PST",
"region": "America",
"locality": "Los_Angeles",
"offset": -7,
"facebook_code": 1
}
},
"4": {
"id": "14060",
"name": "Erez - NordicBet (gianniciano82#gmail.com - 105134566315107)",
"network_id": 1,
"network_type": "Facebook",
"currency": "USD",
"currency_info": {
"prefix": "$",
"postfix": "",
"name": "US Dollars"
},
"timezone": {
"id": 139,
"code": "IST",
"region": "Asia",
"locality": "Jerusalem",
"offset": 3,
"facebook_code": 70
}
},
"5": {
"id": "13672",
"name": "Erez - alon.dan - 1378526859026272",
"network_id": 1,
"network_type": "Facebook",
"currency": "USD",
"currency_info": {
"prefix": "$",
"postfix": "",
"name": "US Dollars"
},
"timezone": {
"id": 92,
"code": "PST",
"region": "America",
"locality": "Los_Angeles",
"offset": -7,
"facebook_code": 1
}
}
}
}
}
Thanks for all the helpers!
GSON library is a good option to convert java object to json string and vise versa.
for converting json to java object use: fromJson(String, Class)
for converting java object to json string use: toJson(Object)
Here is the sample code using [Gson#fromJson()] to convert JSON string into java Map.
Find more examples...
Sample code:
BufferedReader reader = new BufferedReader(new FileReader(new File("resources/json.txt")));
Gson gson = new Gson();
Type type = new TypeToken<Map<String, Map<String, Object>>>() {}.getType();
Map<String, Map<String, Object>> map = gson.fromJson(reader, type);
Map<String, Map<String, Object>> innerMap = (Map<String, Map<String, Object>>) map.get("response").get("data");
for (String key : innerMap.keySet()) {
System.out.println("key:" + key + " id:" + innerMap.get(key).get("id"));
}
output:
key:0 id:15124
key:1 id:13498
key:2 id:14296
key:3 id:13364
key:4 id:14060
key:5 id:13672
Thanks Syam S. for your answer.
$.response.data.*.id indeed work!

Categories