I am working on a Java Spring boot api.
when the the call is made to get /api/home
I want to return this json sample structure.
var response = [
{
"type": "profile-breakdown",
"order": 0,
"grid-width": 6,
"grid-background": "",
"grid-background-url": "",
"title": "",
"contents": {
"name": "Name1",
"avatar" : 1,
"nextSDQ": 4,
"SQDCount": 3
}
},
{
"type": "current-standing",
"order": 1,
"grid-width": 6,
"grid-background": "",
"grid-background-url": "",
"title": "Your current standing summary",
"contents": {
"0": ["emotional distress", "behavioural difficulties", "hyperactivity and concentration difficulties", "difficulties in getting along with other young people"],
"4": ["kind and helpful behaviour"]
}
}
]
--
I've been building the various functions to get "profile-breakdown" and "current-standing" -- I want to append the responses to these to mimic the above structure.
so in MyService where /api/home gets RequestMapped to I begin to hook into my class MyApiHome
MyApiHome myApiHome = new MyApiHome();
JSONObject homeObj = myApiHome.getHomeData();
in MyApiHome -- I want to make "homeObj" in getHomeData an array as opposed to an JSONOBject - but then I start to fall into trouble with casts etc.. I want to build this in such a way - that if getProfileBreakDown is null or decoupled it isn't appended to the homeObj.
public class MyApiHome {
#SuppressWarnings("unchecked")
public JSONObject getHomeData(){
//build clean home object
JSONObject homeObj = new JSONObject();
homeObj.put("profile", this.getProfileBreakDown());
homeObj.put("currentstanding", this.getCurrentStanding());
//HashMap<List<String>, Object> hashMap = new HashMap<List<String>, Object>();
//hashMap.put())
return homeObj;
}
#SuppressWarnings("unchecked")
public Object getProfileBreakDown(){
//build clean home object
JSONObject contents = new JSONObject();
contents.put("name", "Name1");
contents.put("avatar", 1);
contents.put("nextSDQ", 4);
contents.put("SQDCount", 3);
//build clean home object
JSONObject json = new JSONObject();
json.put("type", "profile-breakdown");
json.put("order", 0);
json.put("grid-width", 6);
json.put("grid-background", "");
json.put("grid-background-url", "");
json.put("title", "");
json.put("contents", contents);
return json;
}
#SuppressWarnings("unchecked")
public Object getCurrentStanding(){
String[] stressArray1 = {"emotional distress", "behavioural difficulties", "hyperactivity and concentration difficulties", "difficulties in getting along with other young people"};
String[] stressArray2 = {"kind and helpful behaviour"};
//build clean home object
JSONObject contents = new JSONObject();
contents.put("0", stressArray1);
contents.put("4", stressArray2);
//build clean home object
JSONObject json = new JSONObject();
json.put("type", "current-standing");
json.put("order", 1);
json.put("grid-width", 6);
json.put("grid-background", "");
json.put("grid-background-url", "");
json.put("title", "Your current standing summary");
json.put("contents", contents);
return json;
}
}
To create an array of JSONs, we need to use JSONArray object which has a list of JSONObjects.
So using JSONArray.
I add to a json blob like a data stack.
JSONArray homeObj = new JSONArray();
if(this.getProfileBreakDown() != null){
homeObj.add(this.getProfileBreakDown());
}
if(this.getCurrentStanding() != null){
homeObj.add(this.getCurrentStanding());
}
Related
I'm trying to create the following results in a JSON file:
"numbers": [
{
"small": 2,
"large": 5,
"type": "single"
},
{
"small": 10,
"large": 50,
"type": "double"
}]
I can't seem to figure out how to use JSON Simple to make this happen (coding in Java). When I use:
JSONObject obj = new JSONObject();
obj.put("small", 2);
it doesn't add it to the array. When I create an array:
JSONArray nums = new JSONArray();
nums.add("small", 2)
it doesn't work because add() won't take two parameters.
Please help!
[
{
That means an array ([ ]) of object ({ }).
So:
JSONObject obj1 = new JSONObject();
obj1.put("small", 2);
obj1.put("large", 5);
obj1.put("type", "single");
JSONObject obj2 = new JSONObject();
obj2.put("small", 10);
obj2.put("large", 50);
obj2.put("type", "double");
JSONArray nums = new JSONArray();
nums.add(obj1);
nums.add(obj2);
You have a top level object, which contains one field named "numbers", which is an array of objects, each of which contains three fields.
So it's likely something like:
JSONobject top = new JSONobject();
JSONarray arr = new JSONarray();
top.put("numbers", arr);
then for each element in the array
JSONobject obj1 - new JSONobject();
obj1.put("small", 2);
obj1.put("large", 4);
arr.add(obj1);
etc.
I'm not familiar with that particular API but the details depend only on JSON.
I have this JSON object:
{
"maindrawer":
{
"enabled": true,
"actions":
[
{
"type": "Section",
"title": "Section 1"
},
{
"id": 1,
"type": "Primary",
"title": "Title 1",
"badge":
{
"enabled": false,
"value": 0,
"textColor": "#000000",
"badgeColor": "#ff0990"
},
"subActions":
[
{
"id": 1,
"type": "Primary",
"title": "Sub Title 1"
}
]
}
]
}
}
This is the code I'm using to access the badge -> textColor value:
public void loadJSONFromRaw(Context context, int id)
{
json = null;
try
{
//read and return json sting
InputStream is = context.getResources().openRawResource(id);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
//convert json to object
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> data = new Gson().fromJson(json, type);
//access maindrawer property
Map<String, Object> maindrawer = (Map<String, Object>)data.get("maindrawer");
//access actions list
List<Object> actions = (List<Object>)maindrawer.get("actions");
//return first item in the list
Map<String, Object> action = (Map<String, Object>) actions.get(1);
//return badge object
Map<String, String> badge = (Map<String, String>) action.get("badge");
//access badge -> textColor value
String textColor = badge.get("textColor");
}
catch (IOException e)
{
e.printStackTrace();
}
}
Is there a better/faster or more dynamic way to access JSON nested properties using java/android? I'm using Gson library for this task and don't mind to switch to any other solution to make it easier as this is too much of code to write just to access a single variable.
Ideally, I'm looking for something like:
String textColor = data.get("maindrawer").get("actions").get(1).get("badge").get("textColor");
Also I'm not very interested in using POJO for now.
Lastly, I'm still new to Java so I'm probably missing something here or maybe there are some limitations? anyways thanks for you help!!
Found what I need using JsonPath library. It looks like it does similar to what I need. Here's a sample code I found:
String textColor = JsonPath.parse(json).read("$.maindrawer.actions[1].badge.textColor");
Very clean and straightforward. Hopes this will save someone else's time as well.
Since you are accessing json file locally, it means you know its structure.
So instead of using -
Map<String, Object> data = new Gson().fromJson(json, type);
You can use something like this-
Map<String, MainDrawer> data = new Gson().fromJson(json, type);
where MainDrawer is a class with member variables - enabled, actions and array of another type.
That would make easier to fetch your values like using -
mainDrawer.isEnabled()
Here are two solutions without importing a new library.
Write a simple path parser:
String textColor = (String)parse(data, "maindrawer", "actions", 1, "badge", "textColor");
//...
static Object parse(Object root, Object... params) {
Object current = root;
for (Object p : params) {
if (p instanceof Number) {
current = ((List<?>)current).get(((Number)p).intValue());
} else {
current = ((Map<?,?>)current).get(p.toString());
}
}
return current;
}
Or parse and walk through Gson's JsonElement:
JsonElement root = new Gson().fromJson(json, JsonElement.class);
String textColor = root
.getAsJsonObject().get("maindrawer")
.getAsJsonObject().get("actions")
.getAsJsonArray().get(1)
.getAsJsonObject().get("badge")
.getAsJsonObject().get("textColor")
.getAsString();
You can also do this with BSON using a single line query. You have to cast the object to the type as you go down into Nested JSON objects.
//import java.util.ArrayList;
//import org.bson.Document;
Document root = Document.parse("{ \"maindrawer\" : { \"enabled\" : true, \"actions\" : [{ \"type\" : \"Section\", \"title\" : \"Section 1\" }, { \"id\" : 1, \"type\" : \"Primary\", \"title\" : \"Title 1\", \"badge\" : { \"enabled\" : false, \"value\" : 0, \"textColor\" : \"#000000\", \"badgeColor\" : \"#ff0990\" }, \"subActions\" : [{ \"id\" : 1, \"type\" : \"Primary\", \"title\" : \"Sub Title 1\" }] }] } }");
System.out.println(((String)((Document)((Document)((ArrayList)((Document)root.get("maindrawer")).get("actions")).get(1)).get("badge")).get("textColor")));
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.
I am stuck in getting the data from the JSON file with multiple data sets.
{
"status": "ok",
"count": 3,
"count_total": 661,
"pages": 133,
"posts": [
{
"id": 20038,
"type": "post",
"slug": "xperia-launcher-download",
"url": "http:\/\/missingtricks.net\/xperia-launcher-download\/",
"status": "publish",
"title": "Download Xperia Launcher app for Android (Latest Version)"
},
{
"id": 94,
"type": "post",
"slug": "top-free-calling-apps-of-2014-year",
"url": "http:\/\/missingtricks.net\/top-free-calling-apps-of-2014-year\/",
"status": "publish",
"title": "Best Free Calling Apps for Android November 2014"
},
{
"id": 98,
"type": "post",
"slug": "top-free-calling-apps-of-2016-year",
"url": "http:\/\/missingtricks.net\/top-free-calling-apps-of-2016-year\/",
"status": "publish",
"title": "Best Free Calling Apps for Android December 2016"
}
]
}
I need to access the title, url and status from the above JSON file.
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
List<DataFish> data = new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
DataFish fishData = new DataFish();
fishData.status = json_data.getString("status");
fishData.title = json_data.getString("url");
fishData.sizeName = json_data.getString("title");
data.add(fishData);
}
} catch (JSONException e) {
Toast.makeText(JSonActivity.this, e.toString(), Toast.LENGTH_LONG).show();
Log.d("Json","Exception = "+e.toString());
}
}
I am getting a JSONException with the above code.
What should I do to access the title,status and url from the JSON File?
You have to fetch your JSONArray which is inside a JSONObject , so create a JSONObject and fetch your array with index "posts"
1.) result is a JSONObject so create a JSONObject
2.) Fetch your JSONArray with index value as "posts"
3.) Now simply traverse array objects by fetching it through index
JSONObject jObj = new JSONObject(result);
JSONArray jArray = jObj.getJSONArray("posts");
// Extract data from json and store into ArrayList as class objects
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
DataFish fishData = new DataFish();
fishData.status = json_data.getString("status");
fishData.title = json_data.getString("url");
fishData.sizeName = json_data.getString("title");
data.add(fishData);
}
Note : i don't know weather it is a sample response with shorter version though your json object should ends with } not with , .
[{"id":20038,"type":"post","slug":"xperia-launcher-download","url":"http://missingtricks.net/xperia-launcher-download/","status":"publish","title":"Download
Xperia Launcher app for Android (Latest Version)",
// ^^^ there should be a } not a , to end json
// so make sure to do the correction so it will look like => ...st Version)"},
{"id":94,"type":"post","slug":"top-free-calling-apps-of-2014-year","url":"http://missingtricks.net/top-free-calling-apps-of-2014-year/","status":"publish","title":"Best
Free Calling Apps for Android November 2014", ]
Improvements :
you can use optString to avoid null or non-string value if there is no mapping key
This has two variations
Get an optional string associated with a key. It returns the
defaultValue if there is no such key.
public String optString(String key, String defaultValue) {
fishData.status = json_data.optString("status","N/A");
// will return "N/A" if no key found
or To get empty string if no key found then simply use
fishData.status = json_data.optString("status");
// will return "" if no key found where "" is an empty string
You can validate your JSON here.
If entire JSON getJsonObject() is not working, then you should parse JSON objects & array in multiple arrays then use them.
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);