JSON Java check element is a JSONArray or JSONObject - java

How to check whether an element is a JSONArray or JSONObject. I wrote the code to check,
if(jsonObject.getJSONObject("Category").getClass().isArray()) {
} else {
}
In this case if the element 'category' is JSONObject then it work fine but if it contains an array then it throw exception: JSONArray cannot be converted to JSONObject. Please help.
Thanks.

Yes, this is because the getJSONObject("category") will try to convert that String to a JSONObject what which will throw a JSONException. You should do the following:
Check if that object is a JSONObject by using:
JSONObject category=jsonObject.optJSONObject("Category");
which will return a JSONObject or null if the category object is not a json object.
Then you do the following:
JSONArray categories;
if(category == null)
categories=jsonObject.optJSONArray("Category");
which will return your JSONArray or null if it is not a valid JSONArray .

Even though you have got your answer, but still it can help other users...
if (Law.get("LawSet") instanceof JSONObject)
{
JSONObject Lawset = Law.getJSONObject("LawSet");
}
else if (Law.get("LawSet") instanceof JSONArray)
{
JSONArray Lawset = Law.getJSONArray("LawSet");
}
Here Law is other JSONObject and LawSet is the key which you want to find as JSONObject or JSONArray.

String data = "{ ... }";
Object json = new JSONTokener(data).nextValue();
if (json instanceof JSONObject)
//you have an object
else if (json instanceof JSONArray)
//you have an array
tokenizer is able to return more types: http://developer.android.com/reference/org/json/JSONTokener.html#nextValue()

if (element instanceof JSONObject) {
Map<String, Object> map = json2Java.getMap(element
.toString());
if (logger.isDebugEnabled()) {
logger.debug("Key=" + key + " JSONObject, Values="
+ element);
}
for (Entry<String, Object> entry : map.entrySet()) {
if (logger.isDebugEnabled()) {
logger.debug(entry.getKey() + "/"
+ entry.getValue());
}
jsonMap.put(entry.getKey(), entry.getValue());
}
}

You can use instanceof to check the type of the result that you get. Then you can handle it as you wish.

Related

How to iterrate through Json Array and return each value

I have a Json file that contains an Array of Json Objects:
[{"id":"939f0080-e93e-4245-80d3-3ac58a4a4335","name":"Micha","date":"2021-04-20T11:21:48.000Z","entry":"Wow"}, {"id":"939f0070-e93f-4235-80d3-3ac58a4a4324","name":"Sarah","date":"2021-04-21T11:21:48.000Z","entry":"Hi"}, {"id":"897f0080-e93e-4235-80d3-3ac58a4a4324","name":"John","date":"2021-04-25T17:11:48.000Z","entry":"Hi how are you"}...]
I'm using Json-simple to get the array, but I'm only able to get the object, but not the values.
JSONParser jsonParser = new JSONParser();
try {
FileReader reader = new FileReader("j.json");
Object object = jsonParser.parse(reader);
JSONArray jsonArray = (JSONArray) object;
//prints the first Object
System.out.println("element 1 is" + jsonArray.get(0));
//prints whole Array
System.out.println(jsonArray);
how do i Iterate trough my file and get the values of each date, name date and entry instead of the object?
I want to get something like :
"id is 939f0080-e93e-4245-80d3-3ac58a4a4335 name is Micha date is 2021-04-20T11:21:48.000Z enry is wow"
"id is 939f0070-e93f-4235-80d3-3ac58a4a4324 name is Sarah 2021-04-21T11:21:48.000Z date is 2021-04-21T11:21:48.000Z"
"name is ..."
What you want is basically this
public static void main(String[] args) {
JSONParser jsonParser = new JSONParser();
try (FileReader reader = new FileReader("j.json")) {
Object object = jsonParser.parse(reader);
JSONArray jsonArray = (JSONArray) object;
for (Object o : jsonArray) {
JSONObject jsonObject = (JSONObject) o;
System.out.printf("id is %s name is %s date is %s entry is %s%n", jsonObject.get("id"), jsonObject.get("name"), jsonObject.get("date"), jsonObject.get("entry"));
// Or if you want all
for (Object key : jsonObject.keySet()) {
System.out.printf("%s is %s", key, jsonObject.get(key));
}
System.out.println();
}
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
You can use getOrDefault in case the attribute is optional. There are also countless other libraries which can transform your json into a java object. This will give you more type safety. E.g. jackson or gson.
JSONArray implements Collection and Iterable, so you can iterate over it with a For loop or using an Iterator or Stream. sadly, the object is not generic typed, so you will always get Objects and have to cast them yourself:
for(Object value : jsonArray) {
// your code here //
}
Hope this helps:
JSONParser jsonParser = new JSONParser();
try {
Object object = jsonParser.parse("[{\"id\":\"939f0080-e93e-4245-80d3-3ac58a4a4335\",\"name\":\"Micha\",\"date\":\"2021-04-20T11:21:48.000Z\",\"entry\":\"Wow\"}, {\"id\":\"939f0070-e93f-4235-80d3-3ac58a4a4324\",\"name\":\"Sarah\",\"date\":\"2021-04-21T11:21:48.000Z\",\"entry\":\"Hi\"}, {\"id\":\"897f0080-e93e-4235-80d3-3ac58a4a4324\",\"name\":\"John\",\"date\":\"2021-04-25T17:11:48.000Z\",\"entry\":\"Hi how are you\"}]");
JSONArray jsonArray = (JSONArray) object;
jsonArray.forEach(x -> {
JSONObject o = (JSONObject) x;
String collect = o.entrySet()
.stream()
.map(e -> e.getKey() + " is " + e.getValue().toString())
.collect(Collectors.joining(" "));
System.out.println(collect);
});
} catch (ParseException e) {
e.printStackTrace();
}

How to get dynamically changed Key's value in Json String using java

I'm trying to parse Json string using java, I have stuck up with some scenario.
See below is my JSON String:
"NetworkSettings": {
"Ports": {
"8080/tcp": [ // It will change dynamically like ("8125/udp" and "8080/udp" etc....)
{
"HostIp": "0.0.0.0",
"HostPort": "8080"
}
]
}
}
I try to parse the above json string by using the following code:
JsonObject NetworkSettings_obj=(JsonObject)obj.get("NetworkSettings");
if(NetworkSettings_obj.has("Ports"))
{
JsonObject ntw_Ports_obj=(JsonObject)NetworkSettings_obj.get("Ports");
if(ntw_Ports_obj.has("8080/tcp"))
{
JsonArray arr_ntwtcp=(JsonArray)ntw_Ports_obj.get("8080/tcp");
JsonObject ntwtcp_obj=arr_ntwtcp.get(0).getAsJsonObject();
if(ntwtcp_obj.has("HostIp"))
{
ntw_HostIp=ntwtcp_obj.get("HostIp").toString();
System.out.println("Network HostIp = "+ntw_HostIp);
}
if(ntwtcp_obj.has("HostPort"))
{
ntw_HostPort=ntwtcp_obj.get("HostPort").toString();
System.out.println("Network HostPort = "+ntw_HostPort);
}
}
else
{
ntw_HostIp="NA";
ntw_HostPort="NA";
}
}
else
{
ntw_HostIp="NA";
ntw_HostPort="NA";
}
In my code I have used this code
JsonArray arr_ntwtcp=(JsonArray)ntw_Ports_obj.get("8080/tcp");
to get the value of "8080/tcp"
How can I get the values of dynamically changing key like ("8125/udp","8134/udp", etc...)
Note: I'm using gson library for parsing
After modification
public static void main(String args[])
{
try
{
JsonParser parser = new JsonParser();
JsonObject obj=(JsonObject)parser.parse(new FileReader("sampleJson.txt"));
System.out.println("obj = "+obj);
JsonObject NetworkSettings_obj=(JsonObject)obj.get("NetworkSettings");
if(NetworkSettings_obj.has("Ports"))
{
JsonObject ntw_Ports_obj=(JsonObject)NetworkSettings_obj.get("Ports");
System.out.println("ntw_Ports_obj = "+ntw_Ports_obj);
Object keyObjects = new Gson().fromJson(ntw_Ports_obj, Object.class);
List keys = new ArrayList();
System.out.println(keyObjects instanceof Map); //**** here the statement prints false
if (keyObjects instanceof Map) // *** so controls doesn't enters into the if() condition block *** //
{
Map map = (Map) keyObjects;
System.out.println("Map = "+map);
keys.addAll(map.keySet());
String key = (String) keys.get(0);
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println("Array List = "+jArray);
}
}
}
catch(Exception e)
{
}
}
You can do something like that (not tested but should be ok) :
if (ntw_Ports_obj.isJsonArray()) {
Iterator it = ntw_Ports_obj.getAsJsonArray().iterator();
while (it.hasNext()) {
JsonElement element = (JsonElement) it.next();
if(element.isJsonArray()){
JsonArray currentArray = element.getAsJsonArray();
// Do something with the new JsonArray...
}
}
}
So your problem is the key 8080/tcp is not fixed and it may change. when this situation you can try like this to get the value of the Dynamic key.
Set<Map.Entry<String, JsonElement>> entrySet = ntw_Ports_obj
.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
String key = entry.getKey();
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println(jArray);
}
Edit:
Object keyObjects = new Gson().fromJson(ntw_Ports_obj, Object.class);
List keys = new ArrayList();
/** for the given json there is a one json object within the 'Ports' so the 'keyObjects' will be the 'Map'**/
if (keyObjects instanceof Map) {
Map map = (Map) keyObjects;
keys.addAll(map.keySet());
/**
* keys is a List it may contain more than 1 value, but for the given
* json it will contain only one value
**/
String key = (String) keys.get(0);
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println(jArray);
}

Iterate through JSONObject from root in json simple

I am trying to iterate over a json object using json simple. I have seen answers where you can do a getJSONObject("child") from
{ "child": { "something": "value", "something2": "value" } }
But what if I just have something
{
"k1":"v1",
"k2":"v2",
"k3":"v3"
}
And want to iterate over that json object. This:
Iterator iter = jObj.keys();
Throws:
cannot find symbol
symbol : method keys()
location: class org.json.simple.JSONObject
Assuming your JSON object is saved in a file "simple.json", you can iterate over the attribute-value pairs as follows:
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("simple.json"));
JSONObject jsonObject = (JSONObject) obj;
for(Iterator iterator = jsonObject.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
System.out.println(jsonObject.get(key));
}
You can do like this
String jsonstring = "{ \"child\": { \"something\": \"value\", \"something2\": \"value\" } }";
JSONObject resobj = new JSONObject(jsonstring);
Iterator<?> keys = resobj.keys().iterator();
while(keys.hasNext() ) {
String key = (String)keys.next();
if ( resobj.get(key) instanceof JSONObject ) {
JSONObject xx = new JSONObject(resobj.get(key).toString());
Log.d("res1",xx.getString("something"));
Log.d("res2",xx.getString("something2"));
}
}
In Java 8 we can use lambdas
void handleJSONObject(JSONObject jsonObject) {
jsonObject.keys().forEachRemaining(key -> {
Object value = jsonObject.get(key);
logger.info("Key: {0}\tValue: {1}", key, value);
}
}
Below is the code to iterate through org.google.jso.JsonElemet set and filter out the specific JsonElement by key:
Predicate<Map.Entry<String, JsonElement>> keyPredicate = a -> a.getKey().equalsIgnoreCase(jsonAttributeKey);
Predicate<Map.Entry<String, JsonElement>> valuePredicate = a -> a.getValue()!= null && !a.getValue().isJsonNull();
return responseJson.getAsJsonObject().entrySet().stream()
.filter(keyPredicate.and((valuePredicate)))
.findAny()
.orElseThrow(() -> {
System.out.println(jsonAttributeKey +" tag not exist in the json");
return NGPExceptionFactory.getNGPException(errorCode);
})
.getValue();

how do I find out a JSON Object return JSON Array or string in android

I have a json like the following. how do I find out a JSON Object return JSON Array or string in android.
{
"green_spots": [
......
],
"yellow_spots": "No yellow spot available",
"red_spots": "No red spot available"
}
The JSON objects retrurn Array when values is present else return a String like "No green/red/yellow spot available". I done the with following way. but is there any other way to do? because alert string is changed the If will not work.
JSONObject obj = new JSONObject(response);
String green = obj.getString("green_spots");
// Green spots
if ("No green spot available".equalsIgnoreCase(green)) {
Log.v("search by hour", "No green spot available");
} else {
JSONArray greenArray = obj.getJSONArray("green_spots");
....
}
Object object = jsonObject.get("key");
if (object instanceof JSONObject) {
// It is json object
} else if (object instanceof JSONArray) {
// It is Json Array
} else {
// It is a String
}
You can use instanceof
instead of getString do just obj.get which will return an Object, check if the object is instanceof String or JSONArray
EDIT:
here is a bit of sample code to go with this:
Object itineraries = planObject.get("itineraries");
if (itineraries instanceof JSONObject) {
JSONObject itinerary = (JSONObject) itineraries;
// right now, itinerary is your single item
}
else {
JSONArray array = (JSONArray) itineraries;
// do whatever you want with the array of itineraries
}
JSONObject obj = new JSONObject(response);
JSONArray greenArray = obj.getJSONArray("green_spots");
if(greenArray!=null){
do your work with greenArray here
}else{
Log.v("search by hour", "No green spot available");
}
Simple just print the object like Log.e("TAG","See>>"JsonObject.toString);
if response is in {} block then it is object if it is in [] its array
Warning: This information may be superfluous, but it might prove to be an alternative approach to this problem.
You can use Jackson Object Mapper to convert a JSON file to a HashMap.
public static HashMap<String, Object> jsonToHashMap(
String jsonString) {
Map<String, Object> map = new HashMap<String, Object>();
ObjectMapper mapper = new ObjectMapper();
try {
// convert JSON string to Map
map = mapper.readValue(jsonString,
new TypeReference<HashMap<String, Object>>() {
});
} catch (Exception e) {
e.printStackTrace();
}
return (HashMap<String, Object>) map;
}
This automatically creates a HashMap of appropriate objects. You can then use instanceof or figure out another way to use those objects as appropriate/required.

Test if it is JSONObject or JSONArray

I have a json stream which can be something like :
{"intervention":
{
"id":"3",
"subject":"dddd",
"details":"dddd",
"beginDate":"2012-03-08T00:00:00+01:00",
"endDate":"2012-03-18T00:00:00+01:00",
"campus":
{
"id":"2",
"name":"paris"
}
}
}
or something like
{"intervention":
[{
"id":"1",
"subject":"android",
"details":"test",
"beginDate":"2012-03-26T00:00:00+02:00",
"endDate":"2012-04-09T00:00:00+02:00",
"campus":{
"id":"1",
"name":"lille"
}
},
{
"id":"2",
"subject":"lozlzozlo",
"details":"xxx",
"beginDate":"2012-03-14T00:00:00+01:00",
"endDate":"2012-03-18T00:00:00+01:00",
"campus":{
"id":"1",
"name":"lille"
}
}]
}
In my Java code I do the following:
JSONObject json = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream
JSONArray interventionJsonArray = json.getJSONArray("intervention");
In the first case, the above doesn't work because there is only one element in the stream..
How do I check if the stream is an object or an array ?
I tried with json.length() but it didn't work..
Thanks
Something like this should do it:
JSONObject json;
Object intervention;
JSONArray interventionJsonArray;
JSONObject interventionObject;
json = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream
Object intervention = json.get("intervention");
if (intervention instanceof JSONArray) {
// It's an array
interventionJsonArray = (JSONArray)intervention;
}
else if (intervention instanceof JSONObject) {
// It's an object
interventionObject = (JSONObject)intervention;
}
else {
// It's something else, like a string or number
}
This has the advantage of getting the property value from the main JSONObject just once. Since getting the property value involves walking a hash tree or similar, that's useful for performance (for what it's worth).
Maybe a check like this?
JSONObject intervention = json.optJSONObject("intervention");
This returns a JSONObject or null if the intervention object is not a JSON object. Next, do this:
JSONArray interventions;
if(intervention == null)
interventions=jsonObject.optJSONArray("intervention");
This will return you an array if it's a valid JSONArray or else it will give null.
To make it simple, you can just check first string from server result.
String result = EntityUtils.toString(httpResponse.getEntity()); //this function produce JSON
String firstChar = String.valueOf(result.charAt(0));
if (firstChar.equalsIgnoreCase("[")) {
//json array
}else{
//json object
}
This trick is just based on String of JSON format {foo : "bar"} (object)
or [ {foo : "bar"}, {foo: "bar2"} ] (array)
You can get the Object of the input string by using below code.
String data = "{ ... }";
Object json = new JSONTokener(data).nextValue();
if (json instanceof JSONObject)
//do something for JSONObject
else if (json instanceof JSONArray)
//do something for JSONArray
Link: https://developer.android.com/reference/org/json/JSONTokener#nextValue
Object valueObj = uiJSON.get(keyValue);
if (valueObj instanceof JSONObject) {
this.parseJSON((JSONObject) valueObj);
} else if (valueObj instanceof JSONArray) {
this.parseJSONArray((JSONArray) valueObj);
} else if(keyValue.equalsIgnoreCase("type")) {
this.addFlagKey((String) valueObj);
}
// ITERATE JSONARRAY
private void parseJSONArray(JSONArray jsonArray) throws JSONException {
for (Iterator iterator = jsonArray.iterator(); iterator.hasNext();) {
JSONObject object = (JSONObject) iterator.next();
this.parseJSON(object);
}
}
I haven't tryied it, but maybe...
JsonObject jRoot = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream
JsonElement interventionElement = jRoot.get("intervention");
JsonArray interventionList = new JsonArray();
if(interventionElement.isJsonArray()) interventionList.addAll(interventionElement.getAsJsonArray());
else interventionList.add(interventionElement);
If it's a JsonArray object, just use getAsJsonArray() to cast it. If not, it's a single element so just add it.
Anyway, your first exemple is broken, you should ask server's owner to fix it. A JSON data structure must be consistent. It's not just because sometime intervention comes with only 1 element that it doesn't need to be an array. If it has only 1 element, it will be an array of only 1 element, but still must be an array, so that clients can parse it using always the same schema.
//returns boolean as true if it is JSONObject else returns boolean false
public static boolean returnBooleanBasedOnJsonObject(Object jsonVal){
boolean h = false;
try {
JSONObject j1=(JSONObject)jsonVal;
h=true;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
if(e.toString().contains("org.json.simple.JSONArray cannot be cast to org.json.simple.JSONObject")){
h=false;
}
}
return h;
}

Categories