Building ordered JSON string (GSON library) - java

Below is a simple example of how my JSON should look like . The object has string values for first name and last name, a number value for age and an array value of phone number objects.
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
}
]
}
Here is my code:
// creating JSONObject
JSONObject jsonObj = new JSONObject();
// putting data to JSONObject
jsonObj.put("firstName", "John");
jsonObj.put("lastName", "Smith");
jsonObj.put("age", 25);
// for phone numbers, first create JSONArray
JSONArray jsonArr = new JSONArray();
// create LinkedHashMap
Map<String,String> map = new LinkedHashMap<String, String>();
map.put("type", "home");
map.put("number", "212 555-1234");
// adding map to list
jsonArr.put(map);
map.put("type", "fax");
map.put("number", "212 555-1234");
// adding map to list
jsonArr.put(map);
// putting phoneNumbers to JSONObject
jsonObj.put("phoneNumbers", jsonArr);
// Instantiate a new Gson instance.
Gson gson = new Gson();
// writing JSON to file:"JSONExample.json" in cwd
String json = gson.toJson(jsonObj);
And this is what I'm getting:
{
"map":
{
"firstName":"John",
"lastName":"Smith",
"age":25,
"phoneNumbers":
{
"myArrayList":
[
{
"map":
{
"type":"home",
"number":"212 555-1234"
}
},
{
"map":
{
"type":"fax",
"number":"212 555-1234"
}
}
]
}
}
}
How can I ged rid of "myArrayList" and "map" in the JSON string?
UPDATE
I changed last part of the code:
// writing JSON to file:"JSONExample.json" in cwd
String json = jsonObj.toString();
And it works. But When I modify "firstName" to "first" like this:
// putting data to JSONObject
jsonObj.put("first", "John");
jsonObj.put("last", "Smith");
jsonObj.put("age", 25);
I'm getting disordered string which is weird.
{"last":"Smith","first":"John","age":25,"phoneNumbers":[{"type":"home","number":"212 555-1234"},{"type":"fax","number":"212 555-1234"}]}
I thought GSON library keeps the string ordered.

Try to use elegant-json. This library by default save order of elements.
This JSON:
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
}
]
}
can be made by this code:
new JsonObject()
.add("firstName", new JsonString("John"))
.add("lastName", new JsonString("Smith"))
.add("age", new JsonInt(25))
.add(
"phoneNumbers",
new JsonArray()
.add(
new JsonObject()
.add("type", new JsonString("home"))
.add("number", new JsonString("212 555-1234"))
)
.add(
new JsonObject()
.add("type", new JsonString("home"))
.add("number", new JsonString("212 555-1234"))
)
).toJson();
Note: JSON by definition is not ordered. So try not to depend on order of elements

Related

Parsing JSONObject to access ID when there are multiple ID values (Java)

I am obtaining a JSON response from an API that gives me a list of call records formatted as JSON. I want to parse through the data and find the record ID, my trouble is that each JSON record has multiple ID's and I am not sure how to access the correct one. Keep in mind, I do not know the value of the ID is "3461487000073355176" prior to running the request.
This is my code to receive the JSON, I created a JSONObject so I can hopefully store the value.
1.
Response response = client.newCall(request).execute();
String responseBody = response.body().string();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser parser = new JsonParser();
JsonElement je = parser.parse(responseBody);
String prettyJsonString = gson.toJson(je);
JSONObject json = new JSONObject(prettyJsonString);
System.out.println("Json = " + json);
The JSON the ID I need to access has a comment next to it:
"data": [
{
"Owner": {
"name": "My namen",
"id": "346148700000017",
"email": "m#gmail.com"
},
"$state": "save",
"$process_flow": false,
"Street": "95## ### ######",
"id": "**3461487000073355176**", ----This is the ID I need -----
"Coverage_A_Dwelling": 100000,
"$approval": {
"delegate": false,
"approve": false,
"reject": false,
"resubmit": false
},
"Created_Time": "2020-12-10T09:05:17-05:00",
"Property_Details": "Primary Residence",
"Created_By": {
"name": "My name",
"id": "346148700000017",
"email": "m#gmail.com"
},
"Description": "Created on Jangl: https://jan.gl/crwp773ytg8",
"$review_process": {
"approve": false,
"reject": false,
"resubmit": false
},
"Property_State": "FL",
"Property_Street": "95",
"Roof_Material": "Asphalt Shingle",
"Full_Name": "Clare Em",
"Property_City": "Land ",
"Email_Opt_Out": false,
"Lead_I_D": "4FFEC0C5-FBA1-2463-DB9B-C38",
"Insured_1_DOB": "1942-02-20",
"$orchestration": false,
"Tag": [],
"Email": "cr#yahoo.com",
"$currency_symbol": "$",
"$converted": false,
"Zip_Code": "338",
"$approved": true,
"$editable": true,
"City": "Land O Lakes",
"State": "FL",
"Structure_Type": "Single Family",
"Prior_Carrier": {
"name": "Default Carrier (DO NOT DELETE OR CHANGE)",
"id": "3461487000000235093"
},
"Source": {
"name": "EverQ",
"id": "346148700006474"
},
"First_Name": "Clarence",
"Modified_By": {
"name": "My name",
"id": "3461487000000172021",
"email": "m#gmail.com"
},
"Phone": "7036159075",
"Modified_Time": "2020-12-10T09:05:17-05:00",
"$converted_detail": {},
"Last_Name": "####",
"$in_merge": false,
"$approval_state": "approved",
"Property_Zip": "34638"
}
],
"info": {
"per_page": 200,
"count": 1,
"page": 1,
"more_records": false
}
}
If I understood it correctly, you can get the id like this:
Here, json has the following value.
[
{
"Owner": {
"name": "My namen",
"id": "346148700000017",
"email": "m#gmail.com"
},
"id": "**3461487000073355176**"
...
}
]
Now I can iterate over JSONArray to get the id.
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = (JSONObject) jsonArray.get(i);
String id = (String) jsonObject.get("id");
System.out.println(id);
}
It prints out **3461487000073355176**.
You can do jsonObject.getJSONArray("data"); in your example to obtain JSON array.
The posted JSON response is missing the initial "{".
Your JSON contains data, which is a JSONArray of Owner objects. To get the id field of the first owner (array element 0):
// existing code
JSONObject json = new JSONObject(prettyJsonString);
System.out.println("Json = " + json);
// get the id field
JSONArray dataArray = (JSONArray)json.get("data");
JSONObject data0 = (JSONObject) dataArray.get(0);
JSONObject owner = (JSONObject) data0.get("Owner");
String id = owner.getString("id");
System.out.println(id);
Not sure if understood correctly but if you need to get all the IDs in that "level" why don't you try to model it as a class instead of using parser and let Gson do the parsing (this class might be useful later if you need to add more details)?
For example, defining something like this:
#Getter #Setter
// This models the response string from body
public class Response {
#Getter #Setter
// This models objects in the data list/array
public static class IdHolder {
// Only id because not interested of the rest
private String id;
}
// Only list of id holders because not interested of the rest
private List<IdHolder> data;
}
Then it would be as easy as:
Response res = gson.fromJson(responseBody, Response.class);
// Print out what you got
res.getData().stream().map(IdHolder::getId).forEach(System.out::println);

how to covert JSONObject to another Required JSONObect by mapping AccountId using java

**My result of JSONObject to convert as follows bellow code and have searched for many this how to convert using java but I converted that **
{
"result": {
"accountnames": [{
"accountName": "Hari",
"accountId": 878488
}, {
"accountName": "ravi",
"accountId": 878487
}],
"sales": [{
"accountSales": "89",
"accountId": 878488
}, {
"accountName": "98",
"accountId": 878487
}],
"countResult": [{
"accountResult": "945",
"accountId": 878488
}, {
"accountResult": "9452",
"accountId": 878489
}]
}
}
*and this is where the sample code to be converted *
{
"result": [{
"accountName": "Hari",
"accountSales": "89",
"accountResult": "945",
"accountId": 878488
},
{
"accountName": "ravi",
"accountSales": "98",
"accountId": 878487
},
{
"accountResult": "9452",
"accountId": 878489
}
]
}
My required JSON data has to be formatted as below
You need to group all the elements by accountId. You can use something like this depending on the json library that you are using.
Initialize the json object:
JSONObject rootJson = new JSONObject(json);
JSONObject resultJson = rootJson.getJSONObject("result");
Create a map to hold the objects by accountId:
Map<String, JSONObject> accountIds = new HashMap<>();
Then iterate for each key in the json, then for each element in the arrays and then for each property of the object inside the json:
Iterator mainKeys = resultJson.keys();
while (mainKeys.hasNext()) {
String key = (String) mainKeys.next();
JSONArray array = resultJson.getJSONArray(key);
for (int index = 0; index < array.length(); index++) {
JSONObject object = array.getJSONObject(index);
if (object.has("accountId")) {
String accountId = object.get("accountId").toString();
JSONObject accum = accountIds
.computeIfAbsent(accountId, (k) -> new JSONObject());
// depending on the json impl you can use putAll or similar
Iterator objKeys = object.keys();
while (objKeys.hasNext()) {
String property = (String) objKeys.next();
accum.put(property, object.get(property));
}
} else {
// does not have account id, ignore or throw
}
}
}
Finally create the json file and add the elements to the JSONArray:
JSONObject finalJson = new JSONObject();
finalJson.put("result", new JSONArray(accountIds.values()));
System.out.println(finalJson.toString());
(note: the json has an error in sales array accountName instead of accountSales)

2D JSON Array Not Generated in Correctly Java

I'm trying to generate 2d JSON Array in Java using Json Object, JSON Array. The 2d array being generated is valid but the ordering of elements is wrong.
Java Code...
JSONObject root1 = new JSONObject();
JSONObject c01 = new JSONObject();
JSONObject c11 = new JSONObject();
JSONObject attachment = new JSONObject();
JSONObject payload = new JSONObject();
JSONArray arrayButton= new JSONArray();
JSONArray arrayelements= new JSONArray();
JSONObject elementsObj = new JSONObject();
JSONObject defaultAction = new JSONObject();
root1.put("recipient", c01);
root1.put("message", c11);
c01.put("id", userId);
c11.put("attachment", attachment);
attachment.put("type", "template");
attachment.put("payload", payload);
payload.put("template_type", "generic");
payload.put("elements", arrayelements);
arrayelements.put(elementsObj);
elementsObj.put("title", "Sample Title");
elementsObj.put("image_url", "https://google.com/");
elementsObj.put("subtitle", "Sample Sub Title");
elementsObj.put("default_action", defaultAction);
defaultAction.put("type", "web_url");
defaultAction.put("url", "https://www.google.com/");
defaultAction.put("messenger_extensions", "true");
defaultAction.put("webview_height_ratio", "tall");
defaultAction.put("fallback_url", "https://www.google.com/");
elementsObj.put("buttons", arrayButton);
JSONObject buttons1 = new JSONObject();
buttons1.put("type", "web_url");
buttons1.put("url", "https://google.com");
buttons1.put("title", "show website");
arrayButton.put(buttons1);
JSONObject buttons2 = new JSONObject();
buttons2.put("type", "postback");
buttons2.put("title", "Hi There");
buttons2.put("payload", "sample payload");
arrayButton.put(buttons2);
Expected Output
{
"recipient":{
"id":"USER_ID"
},
"message":{
"attachment":{
"type":"template",
"payload":{
"template_type":"generic",
"elements":[
{
"title":"Sample title",
"image_url":"https://google.com/company_image.png",
"subtitle":"We\'ve got the right hat for everyone.",
"default_action": {
"type": "web_url",
"url": "https://google.com/",
"messenger_extensions": true,
"webview_height_ratio": "tall",
"fallback_url": "https://google.com/"
},
"buttons":[
{
"type":"web_url",
"url":"https://google.com",
"title":"View Website"
},{
"type":"postback",
"title":"Start Chatting",
"payload":"Sample payload"
}
]
}
]
}
}
}
}
Current Output
{
"recipient":{
"id":"988459377921053"
},
"message":{
"attachment":{
"payload":{
"elements":[
{
"buttons":[
{
"type":"web_url",
"title":"show website",
"url":"https://google.com"
},
{
"payload":"sample payload",
"type":"postback",
"title":"Hi There"
}
],
"image_url":"https://s3-ap-southeast-1.amazonaws.com/fls-items-dev/sample-item-4-95/post/sample-item-4-95-primary-4495.png",
"subtitle":"Sample Sub Title",
"title":"Sample Title",
"default_action":{
"fallback_url":"https://www.frrndlease.com/",
"webview_height_ratio":"tall",
"messenger_extensions":"true",
"type":"web_url",
"url":"https://www.frrndlease.com/ItemDetails?uid=wilson-kid-235"
}
}
],
"template_type":"generic"
},
"type":"template"
}
}
}
The order of buttons array, objects template_type & type are inverse. I'm creating nested Json objects and adding them from the outer level to the inner level still the output JSON is not as expected. Can't understand where I'm going wrong.

Google gson.toJson(List) returning response as string instead of array

I am trying to use JsonObject to convert the java object to String. Following is the code that i am using to add the properties :
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("id", favoriteWrapper.getId());
jsonObject.addProperty("menuitemid", favoriteWrapper.getMenuItemId());
jsonObject.addProperty("displayname", favoriteWrapper.getDisplayName());
jsonObject.addProperty("description", favoriteWrapper.getDescription());
jsonObject.addProperty("alias", favoriteWrapper.getAlias());
Gson gson = new Gson();
jsonObject.addProperty("condiments", gson.toJson(favoriteWrapper.getCondiments()));
Here the last property condiments is a list of Long values and following is the response retrieved:
[
{
"id": 1,
"menuitemid": 1,
"displayname": "Ham",
"description": "Ham",
"alias": "Ham",
"condiments": "[1,8,34,2,6]"
}
]
Expected output is as following which is different for condiments:
[
{
"id": 1,
"menuitemid": 1,
"displayname": "Ham",
"description": "Ham",
"alias": "Ham",
"condiments": [1,8,34,2,6]
}
]
What should I do to get the condiments as JSON array rather than String ?
I found the answer to my problem. I used JsonArray and JsonPrimitive to achieve the required response:
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("id", favoriteWrapper.getId());
jsonObject.addProperty("menuitemid", favoriteWrapper.getMenuItemId());
jsonObject.addProperty("displayname", favoriteWrapper.getDisplayName());
jsonObject.addProperty("description", favoriteWrapper.getDescription());
jsonObject.addProperty("alias", favoriteWrapper.getAlias());
JsonArray condiments = new JsonArray();
for (Long condimentId : favoriteWrapper.getCondiments()) {
condiments.add(new JsonPrimitive(condimentId));
}
jsonObject.add("condiments", condiments);
jsonObjects.add(jsonObject);

How do i refactor one JSON array into other format in JAVA?

I have a JSON array like this,
JSONArray content=
"[
{"+"\"pageid\":\"19\","+"\"company\":"+"\"C1\","+"\"pageview\":"+"\"10\","+"\"visitfreq\":"+"\"2\"},{"+"\"pageid\":\"19\","+"\"company\":"+"\"C2\","+"\"pageview\":"+"\"20\","+"\"visitfreq\":"+"\"4\"},{"+"\"pageid\":\"200\","+"\"company\":"+"\"C3\","+"\"pageview\":"+"\"30\","+"\"visitfreq\":"+"\"3\"}
]";
Code for JSONArray:
JSONObject jObj1 = new JSONObject();
jObj1.put("pageid", "19");
jObj1.put("company", "C1");
jObj1.put("pageview", "10");
jObj1.put("visitfreq", "2");
JSONObject jObj2 = new JSONObject();
jObj2.put("pageid", "19");
jObj2.put("company", "C2");
jObj2.put("pageview", "20");
jObj2.put("visitfreq", "4");
JSONObject jObj3 = new JSONObject();
jObj3.put("pageid", "200");
jObj3.put("company", "C3");
jObj3.put("pageview", "30");
jObj3.put("visitfreq", "3");
JSONArray jArr = new JSONArray();
jArr.put(jObj1);
jArr.put(jObj2);
jArr.put(jObj3);
Visual representation:
[
{
"company": "C1",
"visitfreq": "2",
"pageview": "10",
"pageid": "19"
},
{
"company": "C2",
"visitfreq": "4",
"pageview": "20",
"pageid": "19"
},
{
"company": "C3",
"visitfreq": "3",
"pageview": "30",
"pageid": "200"
}
]
I have worked on it to get an out put like below
the out put like this
[{pageid},[{rest of details}] ,{pageid},[{rest of details}] ]
if same pageid occur more than once
it should be like this
[{pageid},[{rest of details1},{rest of details2},.. ],{pageid},[{rest of details}] ]
Looks like you need to create a Map that maps pageid : [{rest of details1},{rest of details2},.. ].
Once you have that Map, you can transform it into your desired output.
Here is the code that will take your JSONArray (the one in the code above) and turn it into Map<String, JSONArray>.
public Map<String, JSONArray> getJsonArrayAsMapOnPageId(JSONArray inputArr) throws JSONException {
//Map holding pageid : [{company:"",pageview:"",visitfreq:""}, ... , ...] mappings
Map<String, JSONArray> idMap = new HashMap<String, JSONArray>();
for (int i=0; i < inputArr.length(); i++) {
JSONObject inputObj = inputArr.getJSONObject(i);
String id = inputObj.getString("pageid");
JSONArray jObjList;
if (idMap.containsKey(id)) {
//append to existing list in the Map
jObjList = idMap.get(id);
} else {
//create new list
jObjList = new JSONArray();
}
JSONObject newJsonObj = new JSONObject();
newJsonObj.put("company", inputObj.get("company"));
newJsonObj.put("pageview", inputObj.get("pageview"));
newJsonObj.put("visitfreq", inputObj.get("visitfreq"));
jObjList.put(newJsonObj);
idMap.put(id, jObjList);
}
return idMap;
}
Here is what it'll look like:
System.out.println("Map looks like:\n" + pageidMap);
Here is what I got:
{
200=[
{
"company": "C3",
"visitfreq": "3",
"pageview": "30"
}
],
19=[
{
"company": "C1",
"visitfreq": "2",
"pageview": "10"
},
{
"company": "C2",
"visitfreq": "4",
"pageview": "20"
}
]
}
I'm not sure exactly in what form (Object, print to output, etc) you want this output to be in, so you can do the final bit of transforming this Map<String, JSONArray> into [{pageid},[{rest of details1},{rest of details2},.. ],{pageid},[{rest of details}] ] without problems.

Categories