I have a following response from a HTTP call which looks like this...
[{"id": 1, "name" : abc, "above50" : true} , {"id": 2, "name" : "xyc", "above50" : false, "kids" : "yes"} ]
I need to iterate through this list and find if there is a key called kids and if there is the key kids, i need to store the value . How do i do it in java?
First you need to parse the json string - it's a list of objects. If you don't have classes to match those objects, by default they can be represented as Map<String, Object>. Then you need to iterate the list, and for every object in it, you have to iterate the entries in the object. If the key matches, store it.
//parse json string with whatever parser you like
List<Map<String, Object>> list = ...;
//iterate every object in the list
for (Map<String, Object> map : list) {
//iterate every entry in the object
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("kids")) {
//you can store the key and the value however you want/need
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-------------------------------------------
#Test
public void test04() throws IOException {
final String preString = "[{\"id\": 1, \"name\" : \"abc\", \"above50\" : true} , {\"id\": 2, \"name\" : \"xyc\", \"above50\" : false, \"kids\" : \"yes\"} ]";
final ObjectMapper objectMapper = new ObjectMapper();
final JsonNode arrayNode = objectMapper.readTree(preString);
if (arrayNode.isArray()) {
for (JsonNode it : arrayNode) {
final JsonNode kids = it.get("kids");
if (kids != null) {
//TODO: Storage this value by you want
System.out.println(kids.asText());
}
}
}
}
You can use JSONObject or JSONArray
String message = ""list" : [{"id": 1, "name" : abc, "above50" : true} , {"id": 2, "name" : "xyc", "above50" : false, "kids" : "yes"} ]";
JSONObject jsonObject = new JSONObject(message);
JSONArray array = jsonObject.getJsonArray("list");
//so now inside the jsonArray there is 2 jsonObject
//then you can parse the jsonArray and check if there is
//a jsonObject that have "kids" like jsonObject.get("kids") != null
// or jsonObject.getString("kids") != null
Related
I have the below json sample and i would like to get the object names dynamically without passing as string.
{
"John": {
"Age": "22",
"status": "married"
},
"Ross": {
"Age": "34",
"status": "divorced"
}
}
I want to get keys John and Ross. I tried with
JSONObject parse = JSON.parseObject("");
for (Map.Entry<String, Object> entry : parse.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
but the above code gives all the keys inside. i only want the parent keys.
you can change parse.entrySet() to parse.keySet() to get the desire result.
JSONObject parse = JSON.parseObject("");
for (Map.Entry<String, Object> entry : parse.keySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
Assuming the use of fastjson. Use keySet instead.
JSONObject parse = JSON.parseObject("");
for (String entry : parse.keySet()) {
System.out.println(entry);
}
This will print:
John
Ross
Tested with:
String s = "{\"John\":{\"Age\":\"22\",\"status\":\"married\"},\"Ross\":{\"Age\":\"34\",\"status\":\"divorced\"}}";
JSONObject parse = JSON.parseObject(s);
for (String entry : parse.keySet()) {
System.out.println(entry);
}
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 have a JSON
{
"info": {
"info1": {
"age": "30",
"city": "New york"
},
"info2": {
"sleeping": "false"
},
"info3": {
"shopping": "false",
"eating": "Buger"
}
},
"data": [{
"name": "XYZ",
"email": "xyz#123.com"
}, {
"name": "ABC",
"email": "ABC#123.com"
}]
}
I need to make a parser that would be generic, and extract names for objects, arrays and individual key pair text.
I will be generating a query using these values.
Only "info" and "data" tags will be fixed rest all can change. We can have empty "info" or different children like "info1", "info2".... "info5" ...
Similarly, individual "info" child can have multiple children like "info1" can have 2 entries or 4 entries.
I tried using jackson library, but not able to traverse the complete json.
UPDATE: using jackson 2.7.2 (latest)
Used following code
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
JsonNode rootNode = mapper.readTree(jsonString);
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());
}
It iterated for the "info" and "data" key. Need to iterate over complete json.
JsonNode can be used to parse whole jsonObject. JsonNode get method can be used to traverse the given JSON.
e.g. :
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(data);
JsonNode infoNode = rootNode.get("info");
Iterator<Map.Entry<String, JsonNode>> infoFieldsIterator = infoNode.fields();
while (infoFieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = infoFieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
JsonNode dataNode = rootNode.get("data");
for (int i = 0; i < dataNode.size(); i++) {
JsonNode dataNodeNum = dataNode.get(i);
Iterator<Map.Entry<String, JsonNode>> dataFieldsIterator = dataNodeNum.fields();
while (dataFieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = dataFieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
}
For more info please check here.
Why not try GSON.
https://github.com/google/gson
You can use models inside models to achieve what you need.
ALL you need to do is serialise data using gson as follows
#SerializedName("info")
private infomodel info;
you can create a seperate model called info model which contains serialized name for its objects.
use the below code to get object from json
Gson gson=new Gson();
Model yourModel=gson.fromJson(<your json object as string>);
I have a json response like this
{
"queryPath": "/api/",
"nId": "f084f5ad24fcfaa9e9faea0",
"statusCode": 707
"statusMessage": "Success",
"results": {
"data": [
{
"id": "10248522500798",
"capabilities": [
"men",
"women"
],
"name": "errt2"
},
{
"id": "418143778",
"capabilities": [
"dog",
"cat"
],
"name": "Livin"
}
]
}
}
Here am adding results.data to a list as follows
private List<HashMap<String, String>> episodes = new ArrayList<HashMap<String, String>>();
episodes =helper.getJSONValue(response, "results.data");
public <T>T getJSONValue(Response res, String path ){
String json = res.asString();
JsonPath jpath = new JsonPath(json);
return jpath.get(path);
}
so episodes contains all data i mean all results.data
While i debuging am getting this way
[{id=10248522500798, name=errt2, capabilities=[men, women]}, {id=418143778, name=Livin, capabilities=[dog, cat]}]
Here i have capabilities [men, women] and [dog, cat].i need to check capability contains men or dog.
How can i do that?
If i were you i haven't done this..
Use gson and map your json into a java model. It's way better. Afterwards you can access all your model parts with getters and setters.
MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
As you see it's very simple :)
But if you want to iterate a list that contains a map you can use code block below:
List<Map<String, String>> test = new ArrayList<Map<String, String>>();
for( Map<String, String> map : test ){
for( Entry<String, String> entry : map.entrySet() ){
System.out.println( entry.getKey() + " : " + entry.getValue() );
}
}
With the code above you can get all the entry's keys and values and check them.
Edit:
You have to change your List to List<Map<String,Object>> after that:
List<Map<String, Object>> test = new ArrayList<Map<String, Object>>();
for( Map<String, Object> map : test ){
for( Entry<String, Object> entry : map.entrySet() ){
if( entry.getKey().equalsIgnoreCase( "capabilities" ) ){
List<String> myCapabilities = ( List )entry.getValue();
if( myCapabilities.contains( "dog" ) && myCapabilities.contains( "cat" ) ){
// BLA BLA
}
}
}
}
It's a nasty way.. I recommend you to use gson..
I converted a map to a Json String using the code below
String msg = new JSONObject(map).toString();
How do I parse the above Json String to get the map back in Android with out using any external libraries?
If you have pairs of String/String you can easily restore it this way:
JSONObject obj = new JSONObject(msg);
Iterator<String> keys = obj.keys();
HashMap<String, String> map = new HashMap<String, String>();
while(keys.hasNext()) {
String key = keys.next();
map.put(key, obj.optString(key));
}
You are asking how to parse but I don't see any JSON to parse in your question.
An example parsing method without any library looks like that:
JSONObject jo = new JSONObject(response);
JSONArray rootArray= jo.getJSONArray("jArray");
int rootArrayLength=rootArray.length();
for(int i=0;i<rootArrayLength;i++){
int id= rootArray.getJSONObject(i).getInt("value");
// do same for others too and create an object
}
// create object and make a list
You can also check from my other answer to compare:
Convert String to JsonArray
You can check my answer here for JSON Parsing:
https://stackoverflow.com/questions/21872643/about-json-parsing-exchange-data-with-rest-services/21872688#21872688
For completeness, please find the details below:
JSONObject is the key class for JSON Parsing. This class represent JSON data in key/value pair where values can be of any type: JSONObjects, JSONArrays, Strings, Booleans, Integers, Longs, Doubles
You create JSONObject as:
JSONObject jObject = new JSONObject(result);
where result is the response you obtain from your HTTPRequest.
Use this jObject to get different types using the specific names:
String:
String jsonString = jObject.getString("NAME");
Array:
JSONArray jsonArray = jObject.getJSONArray("NAME");
Eg. For parsing the places results I used following function, where JSON is something like:
"results" : [
{
"geometry" : {
"location" : {
"lat" : 36.817729,
"lng" : 10.18206
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id" : "35a4f720fff88e2cfb94d64bfd7dbe95a8b4a632",
"name" : "Banque Al-Baraka",
"reference" : "CoQBcwAAAJbocdTKVg8I8CzgDdNtBQQaMsaghRlks-IWYl9eDNmFtftPHMgEfVeek_NHJZ2AN9JbiMda1WvREmoeIHBHsNdz9i7gtBaLM1xB93uhema_oswpqD-eRQ9b3fvTo4MhTOeIa7cRJ70BSEtDMONZqFyjqlGvL-5WsiwmqI1F3Vp_EhArWzyFuNrJdly2cHRBNxUJGhQjlcyHs-U2F0ILpN-ce-PHEesdqA",
"types" : [ "bank", "finance", "establishment" ],
"vicinity" : "88 P9, Tunis"
},
{
"geometry" : {
"location" : {
"lat" : 36.861635,
"lng" : 10.164628
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id" : "da42093835270f902f64bc870154e6787fffbc7b",
"name" : "Agence Ennasr",
"reference" : "CnRwAAAAoh-XuMXghUKtv2UtHQJiRXB0ZugUnAkJIyP-vBd2YzTj5GdwIb5XhUS9x5-uY9_OwyQUdMmUeDHYm4KXHFNvOoj7diOOHAGBu-xCI4svIxcCwQ2w063mc2G3lohiScYMNpbKhwnCaggt0H1iknZY6xIQxDvNwVN0wWkVwO8zf_El5hoUwHgmgFflE31LDLj2_rr0uc1zvZM",
"types" : [ "bank", "finance", "establishment" ],
"vicinity" : "Avenue de Hédi Nouira, Ariana"
},
]
Parsing JSON Array
public ArrayList<HashMap<String,String>> parseResult(JSONObject jsonObject) throws JSONException {
JSONArray jsonArray = jsonObject.getJSONArray(Constants.RESULTS);
ArrayList<HashMap<String, String>> placesList = new ArrayList<HashMap<String,String>>();
for (int i = 0; i < jsonArray.length(); i++) {
Object object = jsonArray.get(i);
if (object instanceof JSONObject) {
placesList.add(parsePlaceInfo((JSONObject) object));
}
}
return placesList;
}
Parsing simple JSON Object
private HashMap<String, String> parsePlaceInfo(JSONObject place) throws JSONException {
String name = place.getString(Constants.NAME);
String icon = place.getString(Constants.ICON);
String vicinity = place.getString(Constants.VICINITY);
JSONObject locationObject = place.getJSONObject(Constants.GEOMETRY).getJSONObject(Constants.LOCATION);
String lat = locationObject.getString(Constants.LAT);
String lng = locationObject.getString(Constants.LNG);
HashMap<String, String> placeDetails = new HashMap<String, String>();
placeDetails.put(Constants.NAME, name);
placeDetails.put(Constants.ICON, icon);
placeDetails.put(Constants.VICINITY, vicinity);
placeDetails.put(Constants.LAT, lat);
placeDetails.put(Constants.LNG, lng);
return placeDetails;
}
Please note that this is not a complete code. I am providing you main details. Please let me know if you need any specific details regarding the code. Thanks!