Java - how to parse both json arrays and objects - java

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.

Related

How to copy all the values from one JSONObject to another?

I understand that it's perfectly possible to copy each individual component over one by one, but it's extremely messy to do and rather ugly. Isn't there a simpler way to copy all the values from one JSONObject to another? Important to note, I am using json-lib. I'm not opposed to switching tools if it's absolutely necessary. Point is, this is a rather inefficient way of doing things.
After hours of searching, I finally found the answer. I'm sort of embarrased that it's this simple.
~
Json-lib has a beautiful feature that allows you to take your current JSONObject and parse the entirety of the JSONObject into a String. And there already exists a method to build a JSONObject from a String. Therefore, all you need to do is turn the JSONObject into a String, and then back into a JSONObject. You could store the string as a variable (or use it as a return value), then simply take your preexisting JSONObject reference and use the method to rebuild the JSONObject from the String. Simple as that.
EDIT - thought I would give a quick code example
JSONObject a = /* pretend a has 100 elements inside */
String temp = a.toString();
JSONObject b = JSONObject.fromObject(temp);
String temp2= b.toString();
if(temp.equals(temp2)){System.out.println("Well done.");}

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

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

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.

Converting JSON Object(s) from file using Java

I have a JSON file with no clue on how data will be in it nor the structure of data.
The only thing known is that it will have either an array of JSON objects or a single JSON object.
I need to get each object from the file and store it as a separate item. In case of array of objects in the file, I should get an array of JSON strings which I can store in DB.
Basically, I need to read this file and separate out each JSON object from it and store it in DB as a string.
One of the ways to do it was to use JACKSON ObjectMapper and assign these items to a Hashmap as key value pairs, but I am not sure though how it can be done If there are list of JSON Objects in the file.
Sample JSON File:
[
{
"name":"Bob",
"type":"Email",
"from":"a#a.com",
"to":"b#B.com",
"attachments":[...],
.
.
.
}
]
Do you know the Object structure that the JSON has(let it be Array or a single one) ? If Yes,
First load the json string form the file into an in memory string.
check the string for Array existence, by searching for '[',']' in the outer structure of multiple occurrences of '{' or '}'
once you know whether you have an array or a single object, you can pass it as object reference to either Jackson or GSON parsers
create in memory Array of JsonObject.class say List. It is actually better to enclose this List inside another class. say myJsonObjects and have a List inside it.
Let us see GSON parsers (by google), though Jackson can also be used in the similar implementation
Gson gson = new Gson();
if(isArray){
myJsonObjects jsonArray = gson.fromJson(jsonStringFromFile,myJsonObjects );
}
else{
gson.fromJson(jsonStringFromFile,JsonObject);
}
http://google-gson.googlecode.com/svn-history/trunk/gson/docs/javadocs/com/google/gson/Gson.html
Jackson is my favorite JSON-to-POJO library. It doesn't really matter where you're loading the JSON from (a URL or from the filesystem), there are handlers for several input sources.
Here's an example:
Map<String,Object> userData = mapper.readValue(new File("user.json"), Map.class);
As far as having an unknown number of JSON structures that you're about to parse, the first thing that comes to mind is to have a mapper for each type you're expecting. You could then wrap the parsing code in try/catch blocks so that if the first fails with whatever exception Jackson gives you when encountering an unexpected format, you can then try the next format and so on.
If you're just trying to generically parse JSON that you don't know the structure of beforehand, you can try something like this:
mapper.readValue(jsonString, new TypeReference<List<EntryType>>() {});
The documentation for Jackson is pretty good-- giving it a solid read-through should definitely help. Here's a good five minute tutorial: http://wiki.fasterxml.com/JacksonInFiveMinutes
I prefer use Gson:
Gson gson;
Map<String, Object>parameters=gson.fromJson(myString);
the rest is iterate the map, i hope help you

alternative to JSONObject in java

I've been using JSONObject as return types on most of my classes and methods for android to aid in debugging and informing the user of the problems. But I've been trying to build an AsyncTask JSONObject has been getting quirky. Is there any multi-type array that can be used to transport primitive data-types in one object?
Perhaps using a
Bundle
would be helpful?
http://developer.android.com/reference/android/os/Bundle.html
If the type doesnt need to be preserved, you could always convert your data to Strings and transport that instead. Then you could use whatever you want; an array, an ArrayList, etc.
If you need to preserve the type, you can use a second value to denote the type. Oryou could still use whatever data structure fits your needs performance-wise and store Object instances; Character for chars, Integer for ints, etc. and then on retrieval, use reflection to get their type info.
Without knowing a little more info, I'd possibly look into using Gson since you say that JSONObject has been quirky for you. I've been using it and haven't had any problems so far:
http://code.google.com/p/google-gson/

Categories

Resources