For a java data handler, I send properly formatted JSON, but a combination of Spring, Java deciding how to cast what it sees, and frameworks I really shouldn't go changing mangle that JSON so that once I can see it, it's turned into a LinkedTreeMap, and I need to transform it into a JsonObject.
This is not to serialize/de-serialize JSON into java objects, it's "final form" is a gson JsonObject, and it needs to be able to handle literally any valid JSON.
{
"key":"value",
"object": {
"array":[
"value1",
"please work"
]
}
}
is the sample I've been using, once I see it, it's a LinkedTreeMap that .toString() s to
{key=value, object={array=[value1, please work]}}
where you can replace "=" with ":", but that doesn't have the internal quotes for the
new JsonParser().parse(gson.toJson(STRING)).getAsJsonObject()
strategy.
Is there a more direct way to convert LinkedTreeMap to JsonObject, or a library to add the internal quotes to the string, or even a way to turn a sting into a JsonObject that doesn't need the internal quotes?
You'd typically have to serialize the object to JSON, then parse that JSON back into a JsonObject. Fortunately, Gson provides a toJsonTree method that kind of skips the parsing.
LinkedTreeMap<?,?> yourMap = ...;
JsonObject jsonObject = gson.toJsonTree(yourMap).getAsJsonObject();
Note that, if you can, just deserialize the JSON directly to a JsonObject with
gson.fromJson(theJson, JsonObject.class);
Related
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?
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.
You can read jsonStr as JSON Object, then convert it to Java Object:
net.sf.json.JSON json = JSONSerializer.toJSON(jsonStr);
YourJavaObject jObj = null;
List<YourJavaObject> list = null;
if(json instanceof JSONObject){
jObj = (YourJavaObject)JSONObject.toBean(JSONObject.fromObject(json), YourJavaObject.class);
}else if(json instanceof JSONArray){
list = JSONArray.toList(JSONArray.fromObject(json), new YourJavaObject(), new JsonConfig());
}
I am trying to parse a json object with this format:
{
'result': (json array or json object) ,
}
The code I am using to parse the json string is:
Map<String, Object> responseMap = new Gson().fromJson(
json,
new TypeToken<HashMap<String, Object>>() {}.getType()
);
When the result field is a JSON object checking with the following line of code returns "LinkedTreeMap"
// returns "LinkedTreeMap"
responseMap.get("result").getClass().getSimpleName()
Likewise, all nested JSON objects are parsed into com.google.gson.internal.LinkedTreeMap. Is there a way to make GSON parse JSON objects into java.util.HashMap by default instead of com.google.gson.internal.LinkedTreeMap.
The usual way to solve this problem seems to be to write a class that defines the structure I'd expect to see in the response JSON object. However, the value contained in the 'result' field can be a JSON object or a JSON array, and I do not have a standard format for the expected return objects and what they may contain.
I have a problem with converting values from Java Request into JSON String.
Im looking for good library, which convert my param keys and values into JSON.
So far I've written a class, which turns my map of params into JSON String. However, as we know, request params keys looks like this:
dto.author.name="Davos"&dto.author.age=47&dto.code="045f"
My class can convert that request params into JSON String which looks like this:
{'author':{'name':'Davos'},'author':{'age':47},'code':'045f'}
which is not quite good for Gson object, because 'author' object inside JSON object is beingrepeated for every 'author' request value, so Gson can't handle that and fill only one repeated object value.
My question is, is there any library, which gets Map of paramerers like
dto.author.name='Davos'
dto.author.age=47
dto.code='045f'
dto.books=[{'title': 'testTitle'}, {'title': 'secondTitle'}]
and can produce JSON String with nested objects based on 'bean' keys? I expect that final output will looks like that ('dto.' key fragment is being removed before execution):
{'author':{'name':'Davos','age':47},'code':'045f','books':[{'title': 'testTitle'},{'title': 'secondTitle'}]}
Any ideas guys? I'm revlolving aroud JSON-simple library, but for now I can't figure out, how it would handle 'bean' keys and convert it into nested JSON objects.
Hi I have a json input file as follows,
{'Latitude':'20',
'coolness':2.0,
'altitude':39000,
'pilot':{'firstName':'Buzz',
'lastName':'Aldrin'},
'mission':'apollo 11'}
How to create a java object from the json input file.
Thanks
You can use the very simple GSON library, with the Gson#fromJson() method.
Here's an example: Converting JSON to Java
There are more than one APIs that can be used. The simplest one is JSONObject
Just do the following:
JSONObject o = new JSONObject(jsonString);
int alt = o.getInt("altitude");
....
there are getXXX methods for each type. It basically stores the object as a map. This is a slow API.
You may use Google's Gson, which is an elegant and better library -- slightly more work required than JSONObject. If you are really concerned about speed, use Jackson.
I have a string in an Android app that I am trying to convert into a JSONObject. The string looks like this (except longer and with actual values instead of the dummy values I entered here):
[[{"1":"a"}],[{"1a":"1a","1b":"1b"},{"2a":"2a","2b":"2b"}]]
I have entered this exact string into two online JSON validators, and both of them confirm it to be valid JSON data. So I would assume that the JSONObject constructor would be able to accept this string and convert it into a JSONObject. But when I try:
json = new JSONObject(result);
Where "result" is a String variable containing the string listed above, I get the following exception:
JSONException: A JSONObject text must begin with '{' at character 1 of [[{"1":"a"}],[{"1a":"1a","1b":"1b"},{"2a":"2a","2b":"2b"}]]
What's going on here? Is the JSONObject's parser broken?
You are trying to create a JSONObject, but what you are actually giving it is a JSONArray. Did you try creating a JSONArray instead?
Alternatively, you could wrap your array in an object so that you can create a JSONObject out of it.
I would suggest using the GSon library instead as it appears to be more full-featured.
In addition, it may be helpful to use this tool to test your data (your data is valid btw):