I want to get a list of friends' names from the Facebook API in Android. In that process, I want to learn how to read JSON objects/Arrays.
I have JSONObject and/or JSONArrays that have been passed to me. I don't know what's in them*. I know how to read the data once I know what fields exist, but I can't read anything as far as I can tell, without a key. Even with the key, How can I tell what's in it?
Basically, I'd like a piece of code that looks like:
JSONArray mArray = response.getJSONArray();
String theEntireDatabase = mArray.getStringOFEntireDatabase();
and have it respond with a String that looks like this:
{
"phoneNumber": [
{
"type": "work",
"num": "11111"
},
{
"type": "home",
"num": "2222"
}
],
"address": {
"state": "World",
"address": "infinite space, 000",
"city": "Android city"
},
"surname": "Swa",
"name": "Android"
}
Having known nothing of what is in the database beforehand?
*it could be "color:" it could be "nuclear threat level:" for all I know.
I tried this, but it only gives keys: Javascript get JSON key Name
JSONArray mArray = response.getJSONArray();
String theEntireDatabase = mArray.toString();
This should work well.
If you want the JSONArray pretty printed you can add this after the code I've just provided you.
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(theEntireDatabase);
String prettyJsonString = gson.toJson(je);
JSONObject#keys will tell you what keys are defined for the object. JSONArray#length will tell you how many entries are in the array (and therefore the range of values you can use for index with the other methods: 0 through length() - 1). JSONObject#toString/JSONArray#toString will give you the string you've asked for.
Take a look at Jacksons built-in tree model feature.
http://wiki.fasterxml.com/JacksonTreeModel
And your code will be:
public void parse(String json) {
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
JsonNode rootNode = mapper.readTree(json);
Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String,JsonNode> field = fieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
}
besides the technical answers (JSONObject#toString(n) seems the easiest - see http://developer.android.com/reference/org/json/JSONObject.html),
I would often use two more pragmatic solutions:
look for an API documentation... I know, it sounds crazy, but some companies do offer such a thing
hack together a short javascript script to try the API and inspect the result in the developer console/firebug/whatever is handy
Related
I am using gson lib to create json from objects. Backend developers are asking to create all values should be in "" quotes event int/long/boolean fields. For example my json looks like that:
{
"age": 26,
"email": "norman#futurestud.io",
"isDeveloper": true,
"name": "Norman"
}
-> i need the following format:
{
"age": "26",
"email": "norman#futurestud.io",
"isDeveloper": "true",
"name": "Norman"
}
Should i change all my fields from int to String or is there any way to do that? Thanks in advance!
To achieve this only way is to store Int as String and then converting the Data class to json String.As Gson use auto typecasting, you can't tell Gson to convert int to String and give you json.
Create the POJO according to your output json that is the only go.
Your code is JavaScript object literal, not a JSON.
Well try this out!
var obj = {"age": 26,"email": "norman#futurestud.io", "isDeveloper":
true, "name":
"Norman"};
for (var k in obj) {
if (obj.hasOwnProperty(k))
{
obj[k] = String(obj[k]);
}
}
{
"id": "1",
"name": "test1",
"data_city": "a:35: {i:22;s:6:\"61,800\";i:23;s:6:\"61,800\";i:24;s:6:\"61,800\";i:25;s:6:\"61,800\" ;i:26;s:6:\"61,800\";i:27;s:6:\"61,800\";i:28;s:6:\"61,800\";i:29;s:6:\"61,800\";i:30;s:6:\"61,800\";i:31;s:6:\"61,800\";i:54;s:6:\"61,800\";i:16;s:6:\"61,800\";i:32;s:6:\"61,800\";i:52;s:6:\"61,800\";i:21;s:6:\"61,800\";i:33;s:6:\"61,800\";i:37;s:6:\"61,800\";i:34;s:6:\"61,800\";i:36;s:6:\"61,800\";i:38;s:6:\"61,800\";i:41;s:6:\"61,800\";i:35;s:6:\"61,800\";i:39;s:6:\"61,800\";i:40;s:6:\"61,800\";i:42;s:6:\"61,800\";i:44;s:6:\"61,800\";i:43;s:6:\"61,800\";i:46;s:6:\"61,800\";i:45;s:6:\"61,800\";i:47;s:6:\"61,800\";i:49;s:6:\"61,800\";i:53;s:6:\"61,800\";i:50;s:6:\"61,800\";i:48;s:6:\"61,800\";i:51;s:6:\"61,800\";}"
}
This is my json response
i need to get data from string data_city
First of all, your JSON is not valid - probably a copy paste error.
Anyway, there are several ways to do this. One option is to use the built in JSONObject type:
String jsonString = "YOUR_JSON_STRING";
JSONObject objJSON = new JSONObject(jsonString);
String dataCity = objJSON.getString("data_city");
Hope this helps. Be sure to run your JSON String through a validation tool first. This one works nicely: https://jsonformatter.curiousconcept.com/
I found a lot of tutorials here, how to parse JSON Data of an JSON Array.
But my JSON File is a little bit complicate (for me). It has the following structure:
JSON File (excerpt)
{
"data": {
"schedule_id": {
"12": {
"name": "CP",
"d_id": [
"7"
]
},
"17": {
"name": "WT",
"d_id": [
"88",
"14"
]
}
}
}
}
Java Code (excerpt)
Info: I've parsed the json into "json" using HTTP GET in another Activity.
JSONObject dataJsonData = json.getJSONObject("data").getJSONObject("schedule_id");
Now I would parse through the ids using a "for"-loop:
ArrayList<String> parsedNameList = new ArrayList<String>();
for (int i = 0; i < idontknow; i++) {
String s = new Integer(i).toString();
parsedNameList.add(dateJsonData.getJSONObject(i).getString("name"));
}
This would add each value of "name" to the ArrayList.
But there are 2 problems:
1. The "schedule_id"s are messed up and incomplete. For example, there is no id "0" and, like in given json, the ids "13, 14, 15, 16" are missing.
2. The "schedule_id"s will be changed every day and will be mixed.
So I don't think, that I can use the predefined integer "i" because some integers aren't a "schedule_id". I could use this loop and would ignore empty entries in the ArrayList, but the JSON contains more than 200 ids - I think it would be more efficient, if there is another way to parse through this json.
I found some informations of the getJSONArray method, but the "d_id"s are Arrays - not the "schedule_ids".
Does anyone has an idea? Is there maybe a placeholder for the parameter of the getString method?
PS: Excuse my english, I'm from germany :)
I think this should work
Iterator keys = dataJsonData.keys();
while(keys.hasNext()) {
// loop to get the dynamic key
String currentDynamicKey = (String)keys.next();
// get the value of the dynamic key
String currentDynamicValue = dataJsonData .getString(currentDynamicKey);
parsedJsonList.add(currentDynamicValue );
}
Source: How to parse a dynamic JSON key in a Nested JSON result?
According to your context, it is better to change the json structure,if you have access to web service.
Request for json structure to be like this,
{
"data":{
"schedule":[
{
"id":12,
"name":"CP",
"d_id":[
"7"
]
},
{
"id":12,
"name":"CP",
"d_id":[
"7",
"88"
]
},
{
"id":200,
"name":"AT",
"d_id":[
"7",
"88"
]
}
]
}
}
Otherwise too much iteration can slow down you CPU.
I have a very basic ASP MVC application exposing a static list of publications (see code and result below).
Code:
public JsonResult Index()
{
List<Publication> list = new List<Publication>() {
new Publication() { Id = 1, Name = "War and Peace" },
new Publication() { Id = 2, Name = "Harry Potter" },
new Publication() { Id = 3, Name = "Cat in the Hat" }
};
return this.Json(list, JsonRequestBehavior.AllowGet);
}
Result:
[{"Id":1,"Name":"War and Peace"},{"Id":2,"Name":"Harry Potter"},{"Id":3,"Name":"Cat in the Hat"}]
When I attempt to consume it in Android I get the following error:
04-15 12:00:57.331: W/System.err(209): org.json.JSONException: A JSONObject text must begin with '{' at character 1 of [{"Id":1,"Name":"War and Peace"},{"Id":2,"Name":"Harry Potter"},{"Id":3,"Name":"Cat in the Hat"}]
I can remove the starting [ and ending ] and it stops the error from appearing. The other option is to put the { publications: logic at the beginning of the android code, but that seems like it should already be there.
How can I update the code in the MVC application to produce a "ready to be consumed" version of JSON?
Any help is greatly appreciated.
First, you shouldn't modify your json string when received, because it may mess up with the parsing.
Second, your Json string is in array format because it starts with [ and ends with ]. So, instead of using JSONObject, you should use JSONArray.
I recommend to use GSON. It's simple to use, fast and accurate.
I've written some code to parse the Google Distance Matrix JSON response received by my Android program. The only piece of data I'm interested in is in the "distance" "value" node.
My code works, but it seems like there must be an easier way to do this. The distance value node is nested pretty deep inside the JSON, but is it really necessary to go through every layer of the JSON to get to the field you want?
Here's my JSON response:
{
"destination_addresses" : [
"5660 Baltimore National Pike, Ingleside Shopping Center, Catonsville, MD 21228, USA"
],
"origin_addresses" : [ "Hilltop Cir, Baltimore, MD 21250, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "3.1 mi",
"value" : 4922 <--THE FIELD I WANT TO EXTRACT
},
"duration" : {
"text" : "11 mins",
"value" : 666
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
And here is the code I used to pull out the distance value:
private double extractDistance(JSONObject json) {
JSONArray rowsArray = null;
double distanceInMiles = -1;
try {
// Getting Array of Distance Matrix Results
rowsArray = json.getJSONArray("rows");
JSONObject rowsObject = rowsArray.getJSONObject(0);//only one element in this array
JSONArray elementsArray = rowsObject.getJSONArray("elements");
JSONObject elementsObject = elementsArray.getJSONObject(0);//only one element in this array
JSONObject distanceObject = elementsObject.getJSONObject("distance");
distanceInMiles = (distanceObject.getDouble("value"))/1609.344; //distance in meters converted to miles
}
catch (JSONException e) {
e.printStackTrace();
}
return distanceInMiles;
}
Thanks!
I recommend you GSON (http://code.google.com/p/google-gson/) which parse the JSON text into a java class instance, and can convert the class instance to JSON text
Jackson is another good third party parser http://jackson.codehaus.org/. Looks like there's a comparison here, http://www.cowtowncoder.com/blog/archives/2009/09/entry_326.html.
Here's an example traversing using a tree, not sure if it qualifies as easier then what you are already doing, http://wiki.fasterxml.com/JacksonTreeModel
Unless you want to go into writing a custom regular expression to search the json string, yes that's going to be the best way of accessing it (and the easiest). Is there a reason you feel you need to access it 'more efficiently'?
If you are willing to include a third party library you might check out http://code.google.com/p/json-path/ .
I know what you feel right now, I had / have same issues with JSON parsing on android where we dont have #getValueforKey kind of features which is embedded on iOS, Even its so obivious google should realize it now, But there is good work done on Gson lib., look for Google Gson Here for easy way to parse json
Here is nice tute : Gson tute