How to parse unpredictable JSON objects? - java

My app parse JSON from an API based on user's selection. Since each user's search might be different I can't predict what the user will search and have a established parsing structure waiting for them every time I finish a API call.
The problem is how can I have a JSON parsing structure in my app that will handle this undefined/unpredictable JSON object from the different API call?
Basically what I need is a way to handle unpredictable and unknown JSON object like they were known and I could parse their keys and the data inside them.
Thank you.

You can use ObjectMapper to convert your JSON to some key-value structure object like Map or HashMap:
Map<String,Object> result = new ObjectMapper().readValue(jsonData, Map.class);
jsonData can be file, stream, byte, string,....
More detail here: https://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/ObjectMapper.html#readValue(byte[],%20java.lang.Class)

I would help more if I had your Code but hope my explanation will work for you. I recently made an app that picks stuff entered by users on the server-side and display on phone. For instance you choose rice and fish while another person chooses rice, fish, coffee and baked beans. These are different stuff but I made an array to hold the stuff, the length of the array depends on the number of stuff you pick. then I build a json object to parse. Note: you can count the number of items the user put and safe in the variable then use that variable as the length.
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString(KEY_SUCCESS).equals("true")) {
JSONArray dataArray = jsonObject.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
JSONObject dataobj = dataArray.getJSONObject(i);
I had saved all user input with "data". One thing my answer may not fit your description because I am not sure if you are getting a list input from user or something like a long paragraph/article. I assumed you are getting a list so I gave you an option to use arrays

Related

How to find first JsonArray DTD

I have a question about key-value pairs in a JSON array. Let's say I want to create a dynamic code that can be used across multiple responses where I want to pick out the first JSON array, how do I go about doing that? Currently, the code below looks for a JSON array known as 'test', but the issue here is that I can only use this code for an endpoint to spits out a JSON array that has the DTD 'test'.
What I was hoping is change the line of code below so that instead of 'test' it will be 0 or first or something like that.
httpResponse.getBody()
.getObject()
.getJSONArray("test")
.getJSONObject(0)
.get("value")
.toString();
Well, it's actually unusual to do that. Because the first item you put into a JSON object is not the first object you retrieve, JSON library puts it in an alphabetic order.
Either way, you can use the static method of JsonObject getNames() and get field names and then retrieve the first name.
EDIT:
Here is an example:
System.out.println(new JSONObject().put("second", "goes second").put("first","goes first").toString());
output:
{"first":"goes first","second":"goes second"}
And the static JSONObject.getNames():
for(String str:JSONObject.getNames(jsOb))
{
System.out.println("key="+str +", value="+jsOb.getString(str));
}
output:
key=first, value=goes first
key=second, value=goes second

Customize Json Patch as per the requiremnent

I am using Json Patch library to perfrom a Patch operation using REST. Now I have the follwoing json document:
{
"id":1,
"ref":{"r1":1,"r2":2}, // header level
"child":[
{
"childId":1,
"ref":{"cc1":1,"cc2":2} // line level
},
{
"childId":2,
"ref":{"cc3":2} // line level
}
]
}
Now As per Json Patch doc we at the header level we can update the ref r1 using the following path /ref/r1 .
Now I am trying to perform operation on the line level child ref. Since child is an array I can use the path /child/0/ref/cc1. But as can be seen from the path I have to specify the index also which is 0 in the previous case.
Now for API consumers asking them to give the index of the array become difficult. So is there any way to customize json patch so that we can bypass the index requirement or what are the other ways to handle this scenario?
I'm not an expert in JSON-Patch, i've just read about it.
from what i understood, is the most important part is to let the API consumers access to your JSON without giving them index,
I think hashmap would help in this case, by getting the index of each element and generate a specific ID for it, then you can save them in the hashmap list, each index has its own ID.
a sample:
HashMap<String, String> elementIndex = new HashMap<[UUID], [elementIndex]>();
you can choose whatever DataType you want, not necessary String
In this case it doesn't matter which index number, it is all about the fixed UUID.
So the path will be in this case /child/{UUID}/ref/cc1 also when you receive the path you can access the UUID and replace it with its elementIndex, now you have the correct path which is /child/0/ref/cc1
and if you want to know how to pass a dynamic value to a JSON Object, there are multiple ways to do it,
this question will help:
How to pass dynamic value to a JSON String, -Convert the JSONObject to String before-
NOTE: It is not necessary to replace it with index, you can do it the way you like could be.
And i believe there are better answers if someone knows more about JSON-patch.
i hope that was helpful, or at least gives you an idea about how to solve it.

when creating JSON, how to avoid getting same data twice into JSON

I need some advice. I´ve built a tool that does image operations for uploaded pictures and saves the results. Each time an operation is done, it creates an entry in a JSON file in its folder.
So if there is no JSON it creates a new one and if there is a JSON it appends the information. The problem is, if someone accidentally adds an image that already had been added, the json appends the information again.
Its too much code to post here, but I would be thankful if someone has some advice on how to compare the files before appending or something else.
"Its too much code to post here", so I am going just to lay down the approach fundamentals :) .
An in memory solution would work if you never use the same folder again after exiting the application. If you count duplicates by a property like picture name, then you can go for a simple solution like a HashMap.
HashMap<String,Boolean> hashMapImages = ...
String newImageName = ...
if (! hashMapImages.containsKey(newImageName)){
hashMapImages.put(newImageName,true);
//... append to JSON
}
If you actually want distinct pictures in content you have to design a hash function for your images. As an example you could use a hash function which sums pixel values every 256 pixels away. For random images it is enough to get a distinctive hash value.
int pos = 0;
long hashsum;
while (pos< image.length){
hashsum += image[pos];
pos += 256;
}
long hashKey = hashsum % 65536; //for a 16 bit key
If you plan to reuse same folder again construct an additional JSON file which contains just the key values (whichever key you choose to use). Parse this JSON file and check if you have the image, before appending.
HashMap<String,Boolean> hashMapImages = loadFromJSONContentFolder();
String key = getKey()
if (! hashMapImages.containsKey(key)){
hashMapImages.put(key,true);
//... append to JSON
}

Array that doesnt gets clear from memory when closing application

I need to have an int array which holds several Integer values. This array should not be clear when the user terminates the application. What I am going to use this for:
Check the last item of this array
if the last item in this array is 6, add 7 to the next item in the array
The array cannot be deleted after the user exits the application, I need this for generating a "subset" of a Unique ID.
So far I've tried using a SQLite database for holding this information, but I think this is to complex way to do it.
Any suggestions?
Well, you can use shared preference which is preferably a less complexion. But the problem is that you can't store a array object. Only primitive types can be stored.
But still here is a example which uses JsonArray to do the same. But it is not a advisory one to do though,.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
JSONArray arr = new JSONArray();
arr.put(12);
arr.put(-6);
prefs.edit().putString("key", arr.toString());
prefs.edit().commit();
// read
try {
arr = new JSONArray(prefs.getString("key", "{}"));
arr.getInt(1); // -6
} catch (JSONException e) {
e.printStackTrace();
}
Taken form here.
Try serializing the array and storing it in a File. (you can use your own logic or use some other custom library like GSON for this purpose)
Next time when the application is launched you can take the file content
and reconstruct the array back.

How do I parse a string of json if I do not know its object model before hand?

I want to work with Open Street Map (OSM). OSM keeps its data formats as flexible as possible by using key value pairs. I am developing an application for Android and I am going to send it a JSON string of OSM data. What should I do if I do not know what the JSON will look like in advance? What would be the best library?
Thanks for your help,
Chris
This may be what you are looking for
http://code.google.com/p/google-gson/
Cheers
First of all, you need to know if the JSON file contains an array or an object. If the first nonwhite space character is a [, it's an array, if it's a {, it's an object. Creating JSONArray when the first char is a { or vice versa will throw a Runtime Exception.
Second off all, once you have your JSONObject, you're going to want to get data from it. So you have to know the name of the keys to get the values, i.e.
myStreet = myJsonOjbect.getString("street name")
If you're not going to get data from it, what's the point of having the json file? Surely you can open the JSON in a Lint to see what the structure is.
hope this helps!

Categories

Resources