We have some code where we read a JSON file into a string and then use Json-lib
to process it as follows:
// ... JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(jsonStr); // ...
We now have a situation where the file is actually a JSONArray (i.e. starts with [
and ends with ]
). The file passes all JSON validation tests but our code raises the following exception:
java.lang.ClassCastException: net.sf.json.JSONArray cannot be cast to net.sf.json.JSONObject
We are able to get past the problem by resorting to the following hack:
// ... JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON("{" + jsonStr + "}"); // ...
Question: Is there a way to process the file, without resorting to the hack?
Advertisement
Answer
Question: Is there a way to process the file, without resorting to the hack?
I am assuming that you are using JSON-lib as implied by the [json-lib]
tag.
I am also assuming that you have encountered this problem in writing the unit tests for your code. (If not … why not?)
In the JSON-lib APIs, JSONObject
and JSONArray
have a common supertype JSON
, so you should be able to assign a JSONObject
or JSONArray
to a variable of type JSON
. (The JSON
interface has methods isObject
and isArray
that allow you to test if a JSON
is an object or an array … but no asObject
or asArray
methods.)
However, if your tests actually require a JSONObject
… you have a problem. In JSON, the “object” and “array” data structures are fundamentally different. Neither is a conceptual subtype of the other. What your “hack” is doing is wrapping the JSON array inside a JSON object. This may or may not be the correct thing to do. (I suspect it isn’t. But if it is the correct thing to do, then the “hack” is a reasonable way to do it. You could also construct a JSONObject
and add the parsed JSONArray
to it programatically.)
If the code under test is designed / specified to work with a JSON object and not with a JSON array, then the CORRECT solution is to reject the input file as bad input, at some point.
If your code under test is designed to do the parsing, then it should throw an exception (or whatever) to reject the bad input file. Your unit test should check that it does that.
If your code under test is designed to take a (parsed)
JSONObject
, then the testcase (the input file containing a JSON array) is a bad testcase. Remove it … for the purposes of this unit test.
In short, the correct solution to your problem is going to depend on what the code you are testing is supposed to do.