Json array in Java - java

I have a JSON array:
**
**
{
"Required" : true,
"Validation" : {
"MaxChars" : "40"
"MinChars" : "10"
}
}
**
**
The code now:
JSONObject formField = formListAdapter.formArray.getJSONObject(i);
if(formField.has("Required") && formField.getBoolean("Required") == true){
}
With the aforementioned code, I can check if in the JSON there is a field with the name "Required" and if this is true. But how can check if the Validation has an attribute inside? and how can I check the name and the value of it?
I.e. how can I check the number of the MaxChars or MinChars?

You can use JSONObject#getJSONObject to get the JSONObject corresponding to the key and then you can perform the same operations to get the values from the key.
JSONObject validationObject = formField.getJSONObject("Validation");
or you can use a better way, Use jackson

JSONObject validationObject = jsonObject.getJSONObject("Validation");
if (validationObject.has("MaxChars")) {
int maxChars = validationObject.getInt("MaxChars");
...
}
// same for MinChars
To get the attribute names for validationObject, you can use:
String[] names = JSONObject.getNames(validationObject);

You have to check the values of the "Validiation" object.
I never had worked with json.org but i belive you can create a new JSONObject from it and read the values like you work with the object in the array.

You want JSONObject.getJSONObject(String field) to get the enclosed JSON object.

Related

Java - Remove Fields from a JSON String recursively without POJOs

How do I remove some fields with a specified name from a JSON string recursively ?
For example, I want to remove the field "secondName" from the following JSON:
INPUT:
{
"name" : "abc",
"secondName": "qwe",
"add" : "abcd",
"moreDetails" : {
"secondName": "qwe",
"age" : "099"
}
}
OUTPUT:
{
"name" : "abc",
"add" : "abcd",
"moreDetails" : {
"age" : "099"
}
}
I have to remove some fields from a lot of different JSONs with different structures/schema, so I won't be able to deserialize/serialize to/from a POJO.
Gson deserializes any valid Json to LinkedTreeMap, like:
LinkedTreeMap<?,?> ltm = new Gson().fromJson(YOUR_JSON, LinkedTreeMap.class);
Then it is just about making some recursive methods to do the clean up:
public void alterEntry(Entry<?, ?> e) {
if(e.getValue() instanceof Map) {
alterMap((Map<?, ?>) e.getValue());
} else {
if(e.getKey().equals("secondName")) { // hard coded but you see the point
e.setValue(null); // we could remove the whole entry from the map
// but it makes thing more complicated. Setting null
// achieves the same.
}
}
}
public void alterMap(Map<?,?> map) {
map.entrySet().forEach(this::alterEntry);
}
Usage:
alterMap(ltm);
You could try storing the JSON as a JSONObject, iterate over the keys using jsonObject.names() and remove the entries using jsonObject.remove(key).
You can do like below if you know the schema and heirarchy:
JsonObject jsonObj= gson.fromJson(json, JsonObject.class);
jsonObj.getAsJsonObject("moreDetails").remove("secondName");
System.out.println(jsonObj.getAsString());
refer this for more info Remove key from a Json inside a JsonObject
else you need to write a dynamic function which will check each and every element of JSON object and try to find the secondName element in it and remove it.
So consider here as you have multiple nested objects then you need to write a function which will iterate over each element and check its type if its again a jsonObject call the same method recursively or iteratively to check against current element, in each check you need to also verify that the key, if it matches with the key which has to be removed then you can remove it and continue the same.
for a hint on how to check a value type of JSON see this How to check the type of a value from a JSONObject?

Looping over an array with alternating elements

Difficult to sum up the question in one sentence. It's easier to show you what I want. I have the following response of a Solr query:
{
.....
},
"facet_counts":{
"facet_queries":{},
"facet_fields":{
"city":[
"New York",23258,
"Los Angeles",13322,
"Paris",1189]},
"facet_ranges":{},
"facet_intervals":{},
"facet_heatmaps":{}}}
I use GSON to parse this JSON data and get a JsonArray containing the array "city". That contains alternating elements for the field name (key) and the corresponding value. So e.g. we have 13322 hits for "Los Angeles". I want to iterate over this array to get out the key=value pairs it contains.
I can think of a number of simple solutions for this task, for example
boolean isKey = true;
String key;
String val;
for(JsonElement je : facetMT) {
if(isKey) {
key = je.getAsString();
isKey = false;
} else {
val = je.getAsString();
resultMap.add(key,val);
isKey = true;
}
}
Or any other way to distinguish the odd and even elements, like checking for divisibility by 2.
But that feels crude. I'm sure Java has some other, elegant way to do this, like working with an iterator and skipping every other element. But I'm not good enough in Java to know how to do that, or any other supersmart way.
Any suggestions, or should I just go with the crude code?
If you're sure about the length of the array then you should read twice at one:
for(int i = 0; i < facetMT.size() - 1; i = i + 2) {
JsonElement key = facetMT.get(i).getAsString();
JsonElement value= facetMT.get(i + 1).getAsString();
resultMap.add(key,val);
}
Note the i < facetMT.size() - 1 condition to avoid IndexOutOfBoundsException
If you are sure that array will always have even amount of elements you can use two of them in one iteration like
Iterator<JsonElement> it = facetMT.iterator();
while (it.hasNext()) {
// iterate over two elements
resultMap.put(it.next().getAsString(), it.next().getAsString());
}
But to be honest proper answer would be enforcing results in form of array of objects like
"city":[
{"cityName":"New York", "amount":23258},
{"cityName":"Los Angeles", "amount":13322},
{"cityName":"Paris", "amount":1189}
]
instead of what you have now
"city":[
"New York",23258,
"Los Angeles",13322,
"Paris",1189
]
This way your code could look like:
for (JsonElement jsonElement : facetMT) {
JsonObject obj = (JsonObject)jsonElement;
resultMap.put(obj.get("cityName").getAsString(),
obj.get("amount").getAsString());
}
In this case use for loop with indexes
For(int i=0;i<...
FaceMT[i]= altered value.
Alterate value doesn't work with iterator for

How to remove empty objects from Json Array

So the json is something like it,
"stores": [
{
"amazon": []
},
{
"flipkart": {
"product_store": "Flipkart",
"product_store_logo": "http://images-api.datayuge.in/image/ZmxpcGthcnRfc3RvcmUucG5n.png",
"product_store_url": "https://price-api.datayuge.com/redirect?id=aHR0cHM6Ly9kbC5mbGlwa2FydC5jb20vZGwvbWktYTEtYmxhY2stNjQtZ2IvcC9pdG1leDl3eHh6M2FtamF0P3BpZD1NT0JFWDlXWFVTWlZZSEVUJmFmZmlkPWFydW5iYWJ1bA",
"product_price": "14999",
"product_offer": "",
"product_color": "",
"product_delivery": "3-4",
"product_delivery_cost": "0",
"is_emi": "1",
"is_cod": "1",
"return_time": "10 Days"
}
},
{
"snapdeal": []
}
]
So the non empty object like flipkart is a JsonObject but all other empty objects are array. So I am so confused about how to remove them.
JSONArray store_array = product_details_json.getJSONObject("data").getJSONArray("stores");
for (int i = 0; i<store_array.length(); i++){
JSONObject store = store_array.getJSONObject(i);
if (!store.getJSONObject(store.keys().next()).has("product_store")){
store_array.remove(i);
}else {
Log.i("Size :",store_array.length()+"");
}
}
But that's not working. I know I am doing this all wrong. Because it has both array and objects so i get the following error
Value [] at amazon of type org.json.JSONArray cannot be converted to JSONObject
Need Help!
I see two problems with your code:
Your JSON structure for "stores" is heterogeneous — some elements have a key that maps to an array and some to an object. That's the immediate cause of the error you are seeing. You can either modify your JSON so everything key maps to an object or code defensively.
When you remove an entry, all subsequent entries move up one space, but since you then increment the loop index i, you skip the entry that just moved into the index you just removed. The easiest way to deal with that is to iterate through store_array in reverse order.
Putting this all together (and assuming you aren't going to change your JSON structure), something like the following (untested) should work:
JSONArray store_array = product_details_json.getJSONObject("data").getJSONArray("stores");
for (int i = store_array.length() - 1; i >= 0; i--){
JSONObject store = store_array.getJSONObject(i);
Object storeData = store.get(store.keys().next());
boolean isValidStore = storeData instanceof JSONObject
&& ((JSONObject) storeData).has("product_store");
if (!isValidStore) {
store_array.remove(i);
}
}

read nested json object using loop

I have been searching from a long time and no solutions is working for me.
I have to retrieve the values from the json object using some loop , and number of nested values is random these can be 1 or may be 10.
json looks like this :
{
"keyInfo":[
{
"name":"ipek",
"key":"1221"
},
{
"name":"ipek",
"key":"1221"
}
],
"terminalInfo":{
"dateExp":"2-2-2",
"deviceId":"1222",
"tid":"122"
}
}
I have tried alot of solutions one of them is this :
JSONObject jsonObject =new JSONObject(jsonString);
JSONObject jsonChildObject = (JSONObject)jsonObject.get("keyInfo");
Iterator iterator = jsonChildObject.keys();
String key = null;
while(iterator.hasNext()){
key = (String)iterator.next();
System.out.println("inval value: "
+ ((JSONObject)jsonChildObject.get(key)).get("inval"));
}
but none of them is working for me please help.
THANKS IN ADVANCE.
You are trying to use an array as a map. jsonChildObject is actually an JSONArray. It does not have keys; for instance you can have the same {"name":"ipek","key":"1221"} multiple times. If you know that the key is unique among items in this array, you can try and build a HashMap out of it if you need, but the structure you have is definitely an array.

Android: Handling json objects that can be a string or array

Ran into a situation where am not sure how to handle it.
I have json data that comes from a server; for example:(am just posting part of the json, so, yes, the json is valid)
"wall_id": 889149,
"poster_image_thumbnail": "http:\/\/www.mface.me\/images\/avatar\/thumb_62441559ddb1dda7513d0f94.jpg",
"post_type": "profile",
"post_content": [{
"text": "",
"images_count": 1,
"images": ["https:\/\/fbcdn-sphotos-a-a.akamaihd.net\/hphotos-ak-ash4\/227408_475848819113499_663318592_n.jpg"]
}]
Created a class to store this json data
public class feedFormat{
Integer wall_id;
String poster_image_thumbnail;
String post_type;
String post_content;
}
There are times when post_content can be empty or an array as the example above. I have declared post_content as String in feedFormat. This is obviously throwing a cast exception (Converting array to string?).
I was expecting JSONObject to read it as a string and later convert it into an array from there, but does'nt seem to go that way.
How can i dynamically handle a string or an array? if it is an array, i need to break it down.
I am porting this app from IOS to android, there is a "id" object in IOS that can be of any class. I check if the class is a NSSTring or NSArray and take it from there. Here in Java, am not sure how to handle it.
Any suggestions are highly appreciated
If your JSON array is empty, it will be like that :
"post_content": []
It will then remain an array, with the particularity of being 0-sized.
Then I suggest you parse directly your JSON array into a appropriate data structure, whatever the size, like an ArrayList> for example. You will then be able to go through all the items of your JSON array, and for each item, add a new HashMap in your arraylist. Every hashmap will contain there pairs of key values.
However, if I understand well your JSON, it seems that it will be always an array of three elements, the third element being itself a array, which size is given bu the attribute images_count. This is not very good, your JSON structure should be :
"post_content": {
"text": "",
"images": [
"https://fbcdn-sphotos-a-a.akamaihd.net/hphotos-ak-ash4/227408_475848819113499_663318592_n.jpg"
]
}
Since images is an array, you can easily get its size.
JSONObject has functions called has(String key) which checks if there is a mapping for a key and isNull(String key) which checks if a particular key is null. Use these to check the key before reading.
public class FeedFormat{
Integer wall_id;
String poster_image_thumbnail;
String post_type;
JSONArray post_content;
}
feedFormat toto = new feedFormat();
toto.post_content = yourJsonObject.getJsonArray("post_content");
This is the easiest way to do what you want. Another way is to create another class.
public class FeedFormat{
Integer wall_id;
String poster_image_thumbnail;
String post_type;
ArrayList<PostContent> post_content = new ArrayList<PostContent>();
}
public class PostContent {
String text;
Integer imageCount;
ArrayList<String> images = new ArrayList<String>();
}
With that you can handle each post content into specific object instead of use JSONObject / JSONArray.
you can check like this jsonobject.has("post_content")
if(jsonobject.has("post_content")) {
/// read array and do remaining stuff
}else {
// if not read another strings and put post_content as null.
}
You can use something like this:
String data= "wall_id": 889149,
"poster_image_thumbnail": "http:\/\/www.mface.me\/images\/avatar\/thumb_62441559ddb1dda7513d0f94.jpg",
"post_type": "profile",
"post_content": [{
"text": "",
"images_count": 1,
"images": ["https:\/\/fbcdn-sphotos-a-a.akamaihd.net\/hphotos-ak-ash4\/227408_475848819113499_663318592_n.jpg"]
}]
JSONArray jArray=data.getJSONArray("post_content");
for(int i=0; i<jArray.length(); i++)
{
JSONObject jObj=jArray.getJSONObject(i);
String text=jObj.getString("text");
int images_count=jObj.getInt("images_count");
String images=jObj.getInt("images");
}

Categories

Resources