How can I get JSONArray values from JSONP? - java

I am creating an Android app that searches for recipes. I am trying to call an API which returns ingredients as JSONP. I need this data for validation purposes, so the user can't enter any invalid ingredients.
I want to get the values from the JSONArray and return the searchValue. But I do not know how to do this as the format of the data is in JSONP and not JSON.
Below is an example of what I am trying to retrieve.
set_metadata('ingredient',
[{"searchValue":"salt","description":"salt","term":"salt"},{"searchValue":"butter","description":"butter","term":"butter"},
When I tried to simply get the array, there was a JSONException. For debugging, i only wanted to return the length of the array, to see how many ingredients were inside the array.
JSONArray ingr = json.getJSONArray("");
System.out.println("Size of the array is: " + ingr.length());
But it didn't like the characters at the start and it gave me this error.
02-29 21:47:38.568 1993-2416/com.example.laptop.whatsfordinner E/JSON Parserīš• Error parsing data org.json.JSONException: Value set_metadata('ingredient' of type java.lang.String cannot be converted to JSONObject
So how can I "ignore" the first part and get values from the JSONArray?

You may do it with simple string operations, substring based on the first index of [ and the last index of ] .
Not too safe or elegant, but as long as the surrounding javascript has more or less known to you (it starts with set_metadata('ingredient', and ends with ); ) you are good to go with it.

Related

Fastest way to parse single value from JSON string

I have a string that I get from a websocket in the below JSON format. I want a very low-latency way to parse the value c associated with the key C. The key names are the same for every packet I get, but the values may differ. So, the key C will stay the same but the value can change from c to something perhaps longer. In my real life application, the number of entries inside X and Y can be much longer.
I've tried a few different approaches, including parsing a single field using Jackson [1], to parsing the full string to JsonNode, but they're all too slow (over 50 microseconds). I thought of finding the position in the String of "C" using [2], and then taking the next few characters after that, but the issue is that the value, c, is variable length so that makes it tricky.
String s = {"A":"a","B":"b","data":[{"C":"c","X":[["3.79","28.07","1"],["3.791","130.05","3"],["3.792","370.8958","5"]],"Y":[["3.789","200","1"],["3.788","1238.1709","4"],["3.787","513.4051","3"]]}'
I'd like something like this:
String valueOfC = getValueOfC(s) // return in only a few microseconds
[1] How to read single JSON field with Jackson
[2] Java: method to get position of a match in a String?
s.substring(s.indexOf("\"data\":[{\"C") + 4, s.indexOf("\"",s.indexOf("\"data\":[{\"C") + 4)));
This is sub-microsecond.

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

How to parse unpredictable JSON objects?

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

How to create a dynamic array with 2 different data types

I need to create a dynamic array with data from a Excel spreadsheet using Apache-POI and Selenium.
My goal is to be able to create a dynamic array with 2 data types(int and String's)to be called to be inputted into a text field using Selenium WebDriver. I have already gotten the information to be hardcoded, however I'd like to be able to not rely on the workbook to increase the speed of my program.
General structure:
for(int i = 0; i < sheet1.getLastRowNum(); i++) {
string cell[i] = formatter.formatCellValue(sheet1.getRow(i).getCell(0)
}
The errors I get are, "Syntax Error on token "i", delete this token" and also "Type mismatch: Cannot convert from "String" to "String[]"
Would it work if you stored everything in the array as a string? You could just use String.valueOf() to convert the cell value to a string, and if you need to get it back later on as an int you could use Integer.parseInt().
You can make an array of Objects, but that could cause more trouble than it's worth. You could be adding an object into it which has a type you never accounted for, which could cause you problems later on down the line.

Parsing weired JSON format

I have to parse JSON. I am using Jackson library to parse it.
My code:
JSONObject root = (JSONObject)parser.parse(response);
JSONArray users = (JSONArray) root.get("response");
Everything would be fine if not a that number in from of elements (1192220) which actually represents a length of a structure. When I am reading it using root.get("response") this number appears to be a first element in users array. I really don't want that. Of course, I can manually truncate an array, but probably it should a better way of doing it. Any suggestions?
{
"response":[
1192220,
{
"uid":39377403,
"first_name":"John",
"last_name":"Smith",
"screen_name":"Super cool guy",
"interests":"N/A"
},
{
"uid":19439900,
"first_name":"Natalie",
"last_name":"Brook",
"screen_name":"nutaloveis",
"interests":"bike"
},
{
"uid":5857176,
"first_name":"James",
"last_name":"Mercer",
"screen_name":"alenkashishkova"
}, .....]
}
Filter it out later
If that number allways is the first element of that array, why dont you just skip it when iterating over the array later on (Start your for-loop at index 1 instead of 0)?
If numbers appear all over the array or at random indexes but you only want to get the objects (e.g. filter out all numbers), you could use javas instanceof operator and check whether it is an instance of JSONObject or Integer and then skip it respectivly.

Categories

Resources