compare and combine two Objects in java which produces as JSON - java

I have two objects of type ClassA<List<List<String>>> which retruns as a JSON from controller. I want to merge these two objects based on two properties(country and operator) if they are equal. Example JSON looks like
#RequestMapping(value = "/controller3"method= RequestMethod.GET produces= MediaType.APPLIACTION_JSON_VALUE)
public ClassA<List<List<String>>> process(HttpServletRequest request) {
ClassA<List<List<String>>> one = service.getvalues();
ClassA<List<List<String>>> two = service.getvaluestwo();
return merge(one, two);
}
JSON1 looks like
"title": "Source",
"dateRange": "23 August 2017 - 21 November 2017",
"total": 336,
"pageSize": 336,
"pageNum": -1,
"nextPageKey": "",
"results": [
[
"India",
"Idea",
"30"
],
"headers": [
"Country",
"Operator",
"Count"
]
JSON2 looks like
"title": "Source",
"dateRange": "23 August 2017 - 21 November 2017",
"total": 336,
"pageSize": 336,
"pageNum": -1,
"nextPageKey": "",
"results": [
[
"India",
"Idea",
"20"
],
"headers": [
"Country",
"Operator",
"Count"
]
I want the Resultant JSON would extracted from RestController from the type ClassA<List<List<String>>> would looks like
"title": "Source",
"dateRange": "23 August 2017 - 21 November 2017",
"total": 336,
"pageSize": 336,
"pageNum": -1,
"nextPageKey": "",
"results": [
[
"India",
"Idea",
"30",
"20",
"50"
],
"headers": [
"Country",
"Operator",
"Count1",
"Count2",
"Total"
]
if there is no match then aggregate them as with zero count of each other.
Can you guys help me?

Related

Getting counts of arrays in a JsonNode

I have a json structure like this:
{
"MetricDataResults": [
{
"Id": "m1",
"StatusCode": "Complete",
"Label": "AWS/EC2 NetworkOut Average",
"Timestamps": [
1518868032,
1518867732,
1518867432
],
"Values": [
15000,
14000,
16000
]
},
{
"Id": "m2",
"StatusCode": "Complete",
"Label": "AWS/EC2 NetworkOut SampleCount",
"Timestamps": [
1518868032,
1518867732,
1518867432
],
"Values": [
15,
14,
16
]
},
{
"Id": "m3",
"StatusCode": "Complete",
"Label": "AWS/EC2 HealthyHostCount",
"Timestamps": [
1518868032,
1518867732,
1518867432
],
"Values": [
15,
14,
16
]
}
]
}
For this json structure I need the counts of arrays in it. I'm looking at the structure to look like something like this:
{
"MetricDataResults (3)": [
{
"Id": "m1",
"StatusCode": "Complete",
"Label": "AWS/EC2 NetworkOut Average",
"Timestamps (3)": [
1518868032,
1518867732,
1518867432
],
"Values (3)": [
15000,
14000,
16000
]
},
{
"Id": "m2",
"StatusCode": "Complete",
"Label": "AWS/EC2 NetworkOut SampleCount",
"Timestamps (3)": [
1518868032,
1518867732,
1518867432
],
"Values (3)": [
15,
14,
16
]
},
{
"Id": "m3",
"StatusCode": "Complete",
"Label": "AWS/EC2 HealthyHostCount",
"Timestamps (4)": [
1518868032,
1518867732,
1518867432,
1518867462,
],
"Values (4)": [
15,
14,
16,
18
]
}
]
}
I'm wondering if there's a particular way with which we get the counts when deserializing with jackson? I was looking at this post - How to get count all json nodes using Jackson framework
but that doesn't seem to completely align with the use case I have. Does anybody have an idea on whether this can be done?

How to parse a flattened Json?

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}

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 equal or not equal two json objects with respect to json path using java

Want to compare two json object, whether both are same in structure with the help of json path.I am not considering values but only structure.Thank you in advance for any help
For example below two json file json-1 and json-2, both are same in structure, but you can see values are different.
json-1
{
"squadName": "Super hero squad",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"members": [
{
"name": "man1",
"age": 50,
"secretIdentity": "Dan",
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"
]
},
{
"name": "Madame Uppercut",
"age": 39,
"secretIdentity": "Jane Wilson",
"powers": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"
]
}
]
}
json-2
{
"squadName": "Super hero1",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"members": [
{
"name": "Man2",
"age": 33,
"secretIdentity": "Jukes",
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"
]
},
{
"name": "Madame Uppercut1111",
"age": 30,
"secretIdentity": "ran",
"powers": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"
]
}
]
}
below two json are of different structure:
{
"squadName": "Super hero1",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"members": [
{
"name": "Man2",
"age": 33,
"secretIdentity": "Jukes",
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"
]
},
{
"name": "Madame Uppercut1111",
"age": 30,
"secretIdentity": "ran",
"powers": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"
]
}
]
}
and
{
"Name": "Super hero1",
"Town": "Metro City",
"year": 2016,
"base": "Super tower",
"IsActive": true,
"associates": [
{
"name1": "Man2",
"age1": 33,
"secretIdentity1": "Jukes",
"powers1": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"
]
},
{
"name1": "Madame Uppercut1111",
"age1": 30,
"secretIdentity1": "ran",
"powers1": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"
]
}
]
I have written code as mentioned below.Getting keys from both json objects
and comparing both.Wanted to verify whether my logic is correct.
List<String>list4 =printJsonObject(obj);
List<String>list5 =printJsonObject(obj1);
if(list5.containsAll(list4)){
boolean res=true;
System.out.println("res"+res);
}
public static List printJsonObject(JSONObject jsonObj) throws
JSONException {
Iterator keys = jsonObj.keys();
List<String> jsonKeys=new ArrayList<String>();
while(keys.hasNext()){
//based on you key types
Object keyObj = (String)keys.next();
Object keyvalue = jsonObj.get(keyObj.toString());
jsonKeys.add(keyObj.toString());
//for nested objects iteration if required
if (keyvalue instanceof JSONObject)
printJsonObject((JSONObject)keyvalue);
}
return jsonKeys;
}
If the structure is consistent, one thing you can do is try to convert those JSON objects by mapping them to a class. If it finds any other key that is not present, it will raise an exception, and by catching it, you know they have different structure. This is enabled by default and can be disabled with the annotation #JsonIgnoreProperties(ignoreUnknown = true) and play around with that.
One good way to do this is by adding Jackson library this is a good link tutorial and doing the following:
class Foo {
#JsonProperty("squadName") String name;
// (other props...)
}

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