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
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");
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"
} ]
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
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"
} ]
} ]
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?