Looping through nested JSON array, getting children with same object model - java

I have a JSON response that looks like the following:
[
{
"id": 5,
"user_id": 1,
"message": "Hello",
"children": [
{
"id": 7,
"user_id": 2,
"message": "Hi",
"children": [
{
"id": 8,
"user_id": 3,
"message": "Hey",
"children": [
]
}
]
}
]
},
{
"id": 6,
"user_id": 4,
"message": "Ahoy",
"children": [
]
}
]
I already have the model created (Message.java). The children can be retrieved by calling getChildren(). The response is saved in a list List<Message> messages.
How can I loop through this JSON array to get the contents of each child until there is no child left? Is this possible without a recursive function?

I Assume you have List messages :
Here is how you can browse through all children with both recursion and iterative way :
List<Message> messages = //you already have that
System.out.println("Using Recusion : ");
for (Message message : messages) {
printMessage(message);
}
System.out.println("Using Iterative : ");
Stack<Message> stack = new Stack<>();
stack.addAll(messages);
while (!stack.empty()) {
Message item = stack.pop();
System.out.println(item.getId() + ":" + item.getUser_id() + ":" + item.getMessage());
for (Message chidren : item.getChildren()) {
stack.push(chidren);
}
}
and here is the printMessage method :
public static void printMessage(Message pmessage) {
System.out.println(pmessage.getId() + ":" + pmessage.getUser_id() + ":" + pmessage.getMessage());
for (Message message : pmessage.getChildren()) {
printMessage(message);
}
}

public void printJsonObject(JSONObject jsonObj) {
for (String keyStr : jsonObj.keySet()) {
Object keyvalue = jsonObj.get(keyStr);
//Print key and value
System.out.println("key: "+ keyStr + " value: " + keyvalue);
//for nested objects iteration if required
if (keyvalue instanceof JSONObject)
printJsonObject((JSONObject)keyvalue);
}
}

Related

Fetching values and sending in an array

I have fetched some integer values from getAPI:
List<String> jsonResponse = response.jsonPath().getList("$");
for (int i = 0; i < jsonResponse.size(); i++) {
if (getJsonPath(response, "type[" + i + "]").equals("agent_sms_missed_call")) {
agentMissedCallId = getJsonPath(response, "id[" + i + "]");
break;
}
}
for (int i = 0; i < jsonResponse.size(); i++) {
if (getJsonPath(response, "type[" + i + "]").equals("caller_sms_missed_call")) {
callerMissedCallSmsId = getJsonPath(response, "id[" + i + "]");
break;
}
}
Now I want to send the value of agentMissedCallId and callerMissedCallSmsId in PUT API : How can i acheive that .
{
"sms_template": [
idFetched(agentMissedCallId), idFetched(callerMissedCallSmsId)
]
}
Response I am getting from a GET API :
[
{
"id": 29169,
"name": "Template 1",
"type": "agent_sms_missed_call"
},
{
"id": 29170,
"name": "Template 2",
"type": "caller_sms_missed_call"
}
]
Request body I want :
{
"sms_template": [
29169
],
"name": "Hello ",
"destination": "hangup||1",
"description": "number for department"
}
This below approach is not recommended, but it doesn't require any 3rd lib, so I think it works for you.
Map<String, Object> body = new LinkedHashMap<>();
body.put("sms_template", List.of(agentMissedCallId, callerMissedCallSmsId));
body.put("name", "Hello ");
body.put("destination", "hangup||1");
body.put("description", "number for department");
given().log().body().contentType(ContentType.JSON)
.body(body)
.post("https://postman-echo.com/post");

Jolt transform JSON array keep rest of the fields

How to keep other fields in the Jolt transform JSON array, I am trying to use wildcard but fields are not added in the final output?
Here is the example input I am using
[
{
"foundduring": "D-DC",
"user_type": "type1",
"location": "location1"
},
{
"foundduring": "D-DG",
"user_type": "type2",
"location": "location2"
},
{
"foundduring": "D-DI",
"user_type": "type3",
"location": "location3"
}
]
I am using the following Jolt transformation and also trying wildcard:
[
{
"operation": "shift",
"spec": {
"*": {
"foundduring": {
"D-DC": {
"#CycleCount": "[&3].foundduring"
},
"D-DG": {
"#Pick": "[&3].foundduring"
},
"D-DI": {
"#Issue": "[&3].foundduring"
}
},
"#": "&"
}
}
}
]
Following is my expected output where shift operation happened and then need to keep all other fields as it it
[
{
"foundduring" : "CycleCount",
"user_type" : "type1",
"location" : "location1"
},
{
"foundduring" : "Pick",
"user_type" : "type2",
"location" : "location2"
},
{
"foundduring" : "Issue",
"user_type" : "type3",
"location" : "location3"
}
]
Actual Output coming:
[
{
"foundduring": "CycleCount"
},
{
"foundduring": "Pick"
},
{
"foundduring": "Issue"
}
]
Consider using "*" wildcard as else case instead of "#" such as
[
{
"operation": "shift",
"spec": {
"*": {
"foundduring": {
"D-DC": {
"#CycleCount": "[&3].&2"
},
"D-DG": {
"#Pick": "[&3].&2"
},
"D-DI": {
"#Issue": "[&3].&2"
}
},
"*": "[&1].&"
}
}
}
]
Btw, no need to get the key name "foundduring", just use &2 substitution to go 2 level up from the current branch and grab that value.
The demo on the site http://jolt-demo.appspot.com/ is
You may consider another library Josson.
https://github.com/octomix/josson
Deserialization
Josson josson = Josson.fromJsonString(
"[" +
" {" +
" \"foundduring\": \"D-DC\"," +
" \"user_type\": \"type1\"," +
" \"location\": \"location1\"" +
" }," +
" {" +
" \"foundduring\": \"D-DG\"," +
" \"user_type\": \"type2\"," +
" \"location\": \"location2\"" +
" }," +
" {" +
" \"foundduring\": \"D-DI\"," +
" \"user_type\": \"type3\"," +
" \"location\": \"location3\"" +
" }" +
"]");
Transformation
JsonNode node = josson.getNode(
"field(foundduring.caseValue('D-DC','CycleCount','D-DG','Pick','D-DI','Issue'))");
System.out.println(node.toPrettyString());
Output
[ {
"foundduring" : "CycleCount",
"user_type" : "type1",
"location" : "location1"
}, {
"foundduring" : "Pick",
"user_type" : "type2",
"location" : "location2"
}, {
"foundduring" : "Issue",
"user_type" : "type3",
"location" : "location3"
} ]

How do I parse this JSON object to get a list of recipe objects that I can then use?

So I am incredibly new to Java and am needing help parsing a JSON response. I already have the method in which I am using to do so, but need help figuring out what exactly I am doing wrong.
I am using an API to retrieve recipes from a site. I am trying to get a list of recipes ("hits" in this case I assume?) that I can then show to the user.
Obviously I need the recipe name ("label" in this case) and other information. Can anyone help me?
Here is the response api response I am getting:
{
"q": "chicken",
"from": 0,
"to": 10,
"more": true,
"count": 168106,
"hits": [
{
"recipe": {
"uri": "http://www.edamam.com/ontologies/edamam.owl#recipe_b79327d05b8e5b838ad6cfd9576b30b6",
"label": "Chicken Vesuvio",
"image": "https://www.edamam.com/web-img/e42/e42f9119813e890af34c259785ae1cfb.jpg",
"source": "Serious Eats",
"url": "http://www.seriouseats.com/recipes/2011/12/chicken-vesuvio-recipe.html",
"shareAs": "http://www.edamam.com/recipe/chicken-vesuvio-b79327d05b8e5b838ad6cfd9576b30b6/chicken",
"yield": 4,
"dietLabels": [
"Low-Carb"
],
"healthLabels": [],
"cautions": [],
"ingredientLines": [
"1/2 cup olive oil",
"5 cloves garlic, peeled",
"2 large russet potatoes, peeled and cut into chunks",
"1 3-4 pound chicken, cut into 8 pieces (or 3 pound chicken legs)",
"3/4 cup white wine",
"3/4 cup chicken stock",
"3 tablespoons chopped parsley",
"1 tablespoon dried oregano",
"Salt and pepper",
"1 cup frozen peas, thawed"
],
"ingredients": [
{
"text": "1/2 cup olive oil",
"weight": 108
},
{
"text": "5 cloves garlic, peeled",
"weight": 15
},
{
"text": "2 large russet potatoes, peeled and cut into chunks",
"weight": 532.5
},
{
"text": "1 3-4 pound chicken, cut into 8 pieces (or 3 pound chicken legs)",
"weight": 1587.5732
},
{
"text": "3/4 cup white wine",
"weight": 169.5
},
{
"text": "3/4 cup chicken stock",
"weight": 180
},
{
"text": "3 tablespoons chopped parsley",
"weight": 11.4
},
{
"text": "1 tablespoon dried oregano",
"weight": 6
},
{
"text": "Salt and pepper",
"weight": 16.46384
},
{
"text": "Salt and pepper",
"weight": 8.23192
},
{
"text": "1 cup frozen peas, thawed",
"weight": 134
}
],
"calories": 4055.7632,
"totalWeight": 2765.59,
"totalTime": 60,
"totalNutrients": {},
"totalDaily": {},
"digest": []
},
"bookmarked": false,
"bought": false
},
{
"recipe": {
"uri": "http://www.edamam.com/ontologies/edamam.owl#recipe_8275bb28647abcedef0baaf2dcf34f8b",
"label": "Chicken Paprikash",
"image": "https://www.edamam.com/web-img/e12/e12b8c5581226d7639168f41d126f2ff.jpg",
"source": "No Recipes",
"url": "http://norecipes.com/recipe/chicken-paprikash/",
"shareAs": "http://www.edamam.com/recipe/chicken-paprikash-8275bb28647abcedef0baaf2dcf34f8b/chicken",
"yield": 4,
"dietLabels": [],
"healthLabels": [],
"cautions": [],
"ingredientLines": [],
"ingredients": [],
"calories": 3033.2012,
"totalWeight": 1824.6125,
"totalTime": 0,
"totalNutrients": {},
"totalDaily": {},
"digest": []
},
"bookmarked": false,
"bought": false
},
{
"recipe": {
"uri": "http://www.edamam.com/ontologies/edamam.owl#recipe_584ac5e486c088b3c8409c252d7f290c",
"label": "Chicken Gravy",
"image": "https://www.edamam.com/web-img/fd1/fd1afed1849c44f5185720394e363b4e.jpg",
"source": "Martha Stewart",
"url": "http://www.marthastewart.com/332664/chicken-gravy",
"shareAs": "http://www.edamam.com/recipe/chicken-gravy-584ac5e486c088b3c8409c252d7f290c/chicken",
"yield": 6,
"dietLabels": [],
"healthLabels": [],
"cautions": [],
"ingredientLines": [],
"ingredients": [],
"calories": 1092.3606,
"totalWeight": 1590.8628,
"totalTime": 270,
"totalNutrients": {},
"totalDaily": {},
"digest": []
},
"bookmarked": false,
"bought": false
},
{},
{},
{},
{},
{},
{},
{}
]
}
This is currently the method I am using to parse the JSON object:
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
final String myResponse = response.body().string();
getActivity().runOnUiThread(new Runnable() {
private Object Date;
#Override
public void run() {
String jsonData = myResponse;
query_result.setText(myResponse);
Log.d("response5", myResponse);
//JSONObject jsonData1 = new JSONObject(myResponse);
JSONObject Jobject = null;
try {
Jobject = new JSONObject(jsonData);
Log.d("jobject", Jobject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray Jarray = null;
try {
Jarray = Jobject.getJSONArray("hits");
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < Jarray.length(); i++) {
JSONObject object;
try {
object = Jarray.getJSONObject(i);
try {
JSONArray Recipe = object.getJSONArray("recipe");
}catch (JSONException e){
e.printStackTrace();
}
for (int j = 0; j < Jarray.length(); j++){
JSONObject object2 = null;
try {
object2 = Jarray.getJSONObject(j);
String Name = object2.getString("label");
String Photo = object2.getString("image");
Log.d("rec_query", " " + Photo);
}catch (JSONException e){
e.printStackTrace();
Log.d("response6:", e.toString());
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
}
});
return null;
}
}
NOTE THE {} {} are just different recipes...it wouldnt fit the whole response
At the moment, when I try to print my variables in the Log, I am getting a message that says the variable is empty (the variable that i used to store the different recipes/"hits".
Your response seems incomplete, it's not in the correct JSON format,Provide the right format and I'll try to help you
String s = "{\n" +
" \"a1\":\"1\",\n" +
" \"b2\":[\n" +
" {\n" +
" \"b21\":\"vb21\"\n" +
" },\n" +
" {\n" +
" \"b22\":\"vb22\"\n" +
" }\n" +
" ]\n" +
"}";
JSONObject object = JSON.parseObject(s);
String vb21 = object.getJSONArray("b2").getJSONObject(0).getString("b21");
like this,and neep to import com.alibaba.fastjson
But i dont`t know if you can use fastjson

How to rearrange json objects within json structure itself? Java

Im trying to restructure duplicate json values in my JSON Structure and rearrange them using the simplest possible method.
I got to the point where I managed to get it stored in a map each time it loops over the JSONObject but from here how do I proceed to store the mapping to achieve my desired outcome? Thank you so much in advance.
public static void main(String[] args) throws JSONException {
String jsonString = "[{\"file\":[{\"fileRefNo\":\"AG/CSD/1\",\"status\":\"Active\"}],\"requestNo\":\"225V49\"},{\"file\":[{\"fileRefNo\":\"AG/CSD/1\",\"status\":\"Inactive\"}],\"requestNo\":\"225SRV\"},{\"file\":[{\"fileRefNo\":\"AG/CSD/2\",\"status\":\"Active\"}],\"requestNo\":\"225SRV\"}]" ;
JSONArray json = new JSONArray(jsonString);
Map<String, Object> retMap = new HashMap<String, Object>();
for (int i = 0; i < json.length(); i++ ) {
if(json != JSONObject.NULL) {
retMap = toMap(json.getJSONObject(i));
System.out.println(retMap + "retMap");
//{file=[{fileRefNo=AG/CSD/1, status=Active}], requestNo=225V49}retMap
//{file=[{fileRefNo=AG/CSD/1, status=Inactive}], requestNo=225SRV}retMap
//{file=[{fileRefNo=AG/CSD/2, status=Active}], requestNo=225SRV}retMap
}
}
}
public static Map<String, Object> toMap(JSONObject object) throws JSONException {
Map<String, Object> map = new HashMap<String, Object>();
Iterator<String> keysItr = object.keys();
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
if(value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if(value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
map.put(key, value);
}
return map;
}
public static List<Object> toList(JSONArray array) throws JSONException {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
if(value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if(value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
list.add(value);
}
return list;
}
Here is my initial JSONArray
[{
"file": [{
"fileRefNo": "AG/CSD/1",
"status": "Active"
}],
"requestNo": "225V49"
}, {
"file": [{
"fileRefNo": "AG/CSD/1",
"status": "Inactive"
}],
"requestNo": "225SRV"
}, {
"file": [{
"fileRefNo": "AG/CSD/2",
"status": "Active"
}],
"requestNo": "225SRV"
}]
Here is my desired outcome
[{
"file": [{
"fileRefNo": "AG/CSD/1",
"status": "Active"
}],
"requestNo": "225V49"
}, {
"file": [{
"fileRefNo": "AG/CSD/1",
"status": "Inactive"
},{
"fileRefNo": "AG/CSD/2",
"status": "Active"
}],
"requestNo": "225SRV"
}]
https://github.com/octomix/josson
Josson josson = Josson.fromJsonString(
"[{" +
" \"file\": [{" +
" \"fileRefNo\": \"AG/CSD/1\"," +
" \"status\": \"Active\"" +
" }]," +
" \"requestNo\": \"225V49\"" +
"}, {" +
" \"file\": [{" +
" \"fileRefNo\": \"AG/CSD/1\"," +
" \"status\": \"Inactive\"" +
" }]," +
" \"requestNo\": \"225SRV\"" +
"}, {" +
" \"file\": [{" +
" \"fileRefNo\": \"AG/CSD/2\"," +
" \"status\": \"Active\"" +
" }]," +
" \"requestNo\": \"225SRV\"" +
"}]");
JsonNode node = josson.getNode("group(requestNo, file).field(file.flatten(1))");
System.out.println(node.toPrettyString());
Output
[ {
"requestNo" : "225V49",
"file" : [ {
"fileRefNo" : "AG/CSD/1",
"status" : "Active"
} ]
}, {
"requestNo" : "225SRV",
"file" : [ {
"fileRefNo" : "AG/CSD/1",
"status" : "Inactive"
}, {
"fileRefNo" : "AG/CSD/2",
"status" : "Active"
} ]
} ]

XMLSerializer missing tags

I have a big problem with XMLSerializer... I use JSON lib (net.sf.json) and this is my code:
public static void main(String[] args) throws Exception {
String xmlInputMsg = "<state>\n" +
" <appId>newID</appId>\n" +
" <newDocuments>\n" +
" <nameValues>\n" +
" <name>test1</name>\n" +
" <value>123456</value>\n" +
" </nameValues>\n" +
" <nameValues>\n" +
" <name>test2</name>\n" +
" <value>987654</value>\n" +
" </nameValues>\n" +
" </newDocuments>\n" +
" <oldDocument>\n" +
" <oldAppId>true</oldAppId>\n" +
" <name>App</name>\n" +
" <source>NA</source>\n" +
" </oldDocument>\n" +
"</state>";
String result = null;
XMLSerializer xmlSerializer = new XMLSerializer();
xmlSerializer.setForceTopLevelObject(true);
result = XMLSerializer.class.toGenericString();
System.out.println(result);
}
My current output is:
"state": {
"appId": "newID",
"newDocuments": [
{
"name": "test1",
"value": "123456"
},
{
"name": "test2",
"value": "987654"
}
],
"oldDocument": {
"oldAppId": "true",
"name": "App",
"source": "NA"
}
}}
But I would like have this msg:
{
"state": {
"appId": "newID",
"newDocuments": {
"nameValues": [
{
"name": "test1",
"value": "123456"
},
{
"name": "test2",
"value": "987654"
}
]
},
"oldDocument": {
"oldAppId": "true",
"name": "App",
"source": "NA"
}
}}
Unfortunately now I missing tag nameValues. Could someone help me with this?

Categories

Resources