Java -JsonArray.contains(string) no such function? - java

I have a JSONArray called playtitles, and a String called playname.
I want to iterate through the JSONArray and check for the String, but JSONArray doesn't have a .contains() function, this is the relevant code:
This is the error I get The method contains(String) is undefined for the type JSONArray
I have tried converting playName to a JSON string but that doesn't seem to work either.
I have also tried using an ArrayList and then converting it to a JSONArray but that causes more problems.
Any tips?

I think you need to use the following implementation:
http://json-lib.sourceforge.net/
According to their specification, there is a .contains() method for JSONArray.
http://json-lib.sourceforge.net/apidocs/net/sf/json/JSONArray.html#contains(java.lang.Object)
So the import would be something like :
import net.sf.json.JSONArray;

Assuming you are using org.json.JSONArray:
Yes, no such method. You will need to implement it yourself.

Related

JAVA - Convert keys JSONObject to lower case

I have a problem related to the keys of a JSONObject. I need to change the keys to lowercase, but I'm not getting it, what's the best way to do this?
Which package is your JSONObject from? If it is from javax.json then it is immutable, hence you need to instantiate a new JSONObject instance and import modified key value pairs into the new instance (from JSONObject Java doc).

javax.json objects have same methods, but they're not implementations of a common interface. How to cast?

I'm dealing with the strange javax.json library. So here's the problem:
I need to cast an Object of type JsonValue to either JsonObject or JsonArray so I can call the methods getJsonObject and getJsonArray of it. Both JsonArray and JsonObject have the same method names with the same functionalities but they're not implemented methods, they are methods defined on each of them! See: JsonObject, JsonArray.
The obvious solution would be to verify the type and then cast depending on the verified type, like this:
if (current.getValueType().equals(JsonValue.ValueType.OBJECT)) {
current = ((JsonObject) current).getJsonObject(node);
} else if (current.getValueType().equals(JsonValue.ValueType.ARRAY)) {
current = ((JsonArray) current).getJsonObject(node);
}
but it'd require too many repetitions on my code. So I ask:
1) If both JsonObject and JsonArray have the same methods, why they're not implementations of some interface?
2) Is there a more elegant way to cast the object to JsonObject or JsonArray at the same time by using some trick? Do you know any way to make this situation better?
Although the 2 methods on the 2 different objects have the same name, their signatures are in fact different. JsonObject#getJsonObject(String) accepts a String key identifying the value to pull from a JSON object of key-value pairs. JsonArray#getJsonObject(int) accepts an int index identifying which element to pull the value from in a JSON array.
In this case, there is no appropriate common interface that the 2 classes can share. Your code will have to know whether to inspect a JSON object or a JSON array and cast accordingly.
Since the 2 methods in question do not have the same signature, there are not other alternatives for calling them in a "common way". You could potentially use reflection, but this risks making the code more confusing. For example, Apache Commons includes MethodUtils#invokeMethod. You could potentially use that to invoke any method named "getJsonObject", accepting any kind of object (either String or int). Although using this would make it "common code" across both cases, it's potentially confusing for people reading the code later. They'd have to keep track of the fact that this is using reflection, and that the passed argument might be either String or int, and that it really all works out thanks to it being either a JSON object or array. Instead, I would favor just doing the downcast in this case.
Chris is right, Your code will have to know whether to inspect a JSON object or a JSON array and cast accordingly. However, if you are ok with adding an external library, I would recommend gson for parsing Json
This library has JsonElement class which should fit good in your case. look at this to see how it works

What's the complexity of getJSONObject and getJSONArray methods?

I'm using org.json library as JSON-client for my Java application and I would like to know the complexity of some methods from this lib.
I'm retrieving thousands of JSON objects inside a JSON array inside another JSON objects (and so on) from a database via it's HTTP API. As an example (and only as an example, my case is much more complex), suppose that I'm doing something like that:
// Ignoring attributes types
import org.json.*;
public static void main(String[] args) {
response = MyHTTPClient.post(url, query).asJSON();
response = JSON.parse(response);
data = response.getJSONObject(1).getJSONArray("results").getJSONObject(0);
}
What's the complexity of getJSONObject(int) and getJSONArray(String) methods from org.json library? Is it running in a constant [O(1)] or linear [O(n)] time? If none, what's the correct answer?
org.json will parse the entire JSON document when you instantiate the JSONObject from a string (or JSONTokener). The getJSONObject() and getJSONArray() methods are just typed versions of the untyped get() methods (which return Object instance). if you look at the source you can see that JSONObject uses a HashMap while JSONArray uses an ArrayList for internal representations, so the execution times are close-to-constant (O(1))
Both getJSONArray and getJSONObject and methods eventually call opt(String paramString) method which gets value from a HashMap. So they should work in close to constant time i.e. O(1) ideally. Here's a code snippet:
public Object opt(String paramString)
{
return paramString == null ? null : map.get(paramString);
}
You can look at the source code yourself and dig in.

Java - how to parse both json arrays and objects

i am using the org.json package in Java (Android) and I am just stumbled with a simple problem.
The webserver returns an array if everything is okay, but an json object { error : true, ...} if something went wrong.
How can I parse that into a common object - I mean both arrays and objects are json after all, but it seems JSONArray and JSONOBject don't share an interface in common.
Am I missing something?
Use JSONTokener.nextValue() and check if the result is a JSONObject or a JSONArray (using instanceof).
The real answer is ... fix the webserver and have it return a consistant result. Otherwise, you basically are going to have to manually inspect the returned data to see what it is.
Another option is catching the JSONException the constructor for JSONArray will throw when it isn't an array which would indicate to you that you should try JSONObject.

Access nested json data in single get?

I am trying to trying to get a value out of a json object. How would I get a third level json object:
json format looks like:
feedString = {"level1":[{"level2":{"level3":{"valueIWant":10}}}]}
Code is:
JSONObject jsonFeed = new JSONObject(feedString);
jsonFeed.get("level1.level2.level3.valueIWant");
Can I get nested levels in one get? What should my key look like?
You could give JSONiJ (JSON in Java) a shot; it's a Java version of JSONPath and basically maps (a subset of) XPath syntax onto JSON objects.
Also, see this SO question for some other ideas; it looks like json-path has a Java version, and uses dot notation.
The other option is to build an EL bridge between JSONObjects and something like MVEL or OGNL, which would give you the more-familiar dot notation. (I thought there was an MVEL/JSON bridge, but can't find it now.)
You should use JSONPath. Check out this Java implementation http://code.google.com/p/json-path/
It's been a while now, but I have some good news. Just tried beanutils and it works like a charm!
Assuming you have the json converted to map: (any parser can do that)
private Map<String, Object> json;
All you need is:
PropertyUtils.getProperty(json, "level1.level2.level3.valueIWant")
Have fun :)

Categories

Resources