I have seen this question and understand the answer, but can not use it in my scenario.
My scenario: I retrieve data via JPA from a mysql database and want to put this data into a JSONObject like this
{
"A":["1","2","3"],
"B":["1","2","3","4"],
"C":["1","2"]
}
The problem is I do not know how many arrays I will retrieve. It could be 1 or it could be 200, depending on the data in the database.
If I append the data into a JSONObject like this:
import org.apache.tapestry5.json.JSONObject
// ...
JSONObject data = new JSONObject();
for (Value val : values) data.append(val.getName(), val.getValue());
I'll get
{"val_name": [[["1"],"2"],"3"], ...}
Is there a way to use JSONOBject.append without creating JSONArrays and puting them into the JSONObject, which will result in a nested JSONObject?
A JSON object is a "dictionary" -- a map between name and value. A JSON array is a sequential list of values, with only the ordinal position of the value identifying it. It makes no sense to "append" to the object -- you add new name/value pairs to it (although they apparently call it appending, just to confuse you). If, within an object, you want something like "A":["1","2","3"] then you necessarily must insert an array (as the value of a name/value pair) into the object.
But note that either before inserting the array into the object or after you can append additional values to the array. You just need to get/save a reference to the array.
In your above example you're making the mistake of appending to the object rather than the array.
Related
I have a JSON string that I am using within a Scala programme by converting it into a ListMap to perform some tests, and then returning the results in an output JSON, along with the original JSON as a value. I cannot use a schema as the JSONs are changeable. The original JSON string is for example:
val originalJSONString =
{
"outerKey1": "",
"outerKey2": "",
"outerKey3": {
"innerKey1": "",
"innerKey2": "",
"innerKey3": ""
}
}
When I convert it to a ListMap using the below code, it will preserve the order of the outer keys, but not the inner keys as Object doesn't preserve the order.
val jsonListMap = mapper.readValue[ListMap[String, Object]](originalJSONString)
If I create a JSON that just contains the "outerKey3" key and its values, and the following code, it will preserve the order, but naturally will not work on the whole of the originalJSONString. The JSONs will always only have nesting of two levels.
val jsonListMap = mapper.readValue[ListMap[String, ListMap[String, String]]](originalJSONString)
There must surely be some way within this code to convert the keys with string values to Object/String and the keys with Map/ListMap values (i.e. outerKey3) to a ListMap? I want it to infer which data type it should be creating.
I was thinking about creating a function, or using Either/Option but I'm not sure these are appropriate.
(I am aware that JSON is by definition unordered and Scala/Java do not preserve order for this reason. Unfortunately without being able to convert the necessary values to ListMap the final JSON is unordered and the humans who will be reading it - not querying it - want it in order. I do not want to return the original string as the formatting would make my querying of the output JSON a nightmare. Also I would like to know if inferring data type in this way is possible for many other data wrangling issues outside of preserving JSON key order!)
Thank you in advance!
I have a JSON which is mentioned below.
{"Orders"
[{"BusinessUnit":"TS",
"DeliveryDetails":
[{"SlotStartDateTime":"2015-03-30T16","DeliveryOption":"Home
Delivery","ReservationID":"13349259","PersonInfoShipTo":
{"Address":"OrganizationName":"HP","BuildingTypeID":"",
"IsCommercialAddress":"false","PostalCode":"56001",
"City":"Bangalore","AddressLine3":"A3","AddressLine2":"A2",
"AddressLine1":"A1","IsPAFValidated":"true",
"GridRef":"0473601734","State":"KA","AddressLine4":"A4",
"Country":"IN"}},"ShipNode":"NODEUK","SlotEndDateTime":"2015-
03-30T17"}],
"FulfilmentID":"a9466f83-938d-4115-a3d4-62ff4bdcd1b6",
"OrderTypeIndicator":"SalesOrder"}]}
Question:
I am able to take the values of BusinessUnit, FulfilmentID & OrderTypeIndicator. But, I am unable to take the values present inside the inner json object DeliveryDetails. Could anyone help me on taking those values
"DeliveryDetails" is mapped to a json array object with a single json object inside.
Try doing:
json.getJSONArray("Orders").get(0).get("DeliveryDetails").get(0)
Of course it would be better to check first if keys exists and the size of json arrays returned before retrieving actual indices.
I'm trying to get a value from the databae.
My Database query:
String GroupID1="select idCompanies from companies where Company_Name='ACME';";
here I'm calling to a javabeans which give back an ArrayLIst with one element
ArrayList<?> IdGroup1=oper.getList(GroupID1);
then, I print the result:
System.out.println(IdGroup1);
The query works fine, however I'm getting as a result:
[javabeans.ListOneElement#609f6e68]
Instead of the real value. How can I convert the java object to the real value?
you are printing the ArrayList object IdGroup1,You need to iterate to get the alues
This code will retrieve the first (and only) item from the list:
System.out.println(IdGroup1.get(0).toString());
Adding the following will prevent a nullPointerException:
if (!IdGroup1.isEmpty())
System.out.println(IdGroup1.get(0).toString());
-Added .toString() to get the value of the object
Consider what type of Object oper.getList(GroupID1) will return.
You need to accommodate for whatever object that is and then convert it to String.
You need to:
Unpackage your list (that is a list contains, and is expected by java to possibly contain multiple objects, so it doesn't automatically 'unpack' it for you if you have a list of 1 object)
Extract your string. Here java might cleverly convert a number (int, float, etc. ) to a string for you.
For part two, look at what you expect the object to be by finding the JavaDocs for whatever package is handling your database queries. Then see how to extract your string.
It might be as simple as System.out.println(IdGroup1.get(0).toString());
Where get(0) unpackages the object from the list, and toString() extracts the string.
If you still get back javabeans.ListOneElement#41ccdc4d try other methods to extract your string....toValue() perhaps? It depends on the packages you're using.
How can I convert a List to a Json String?
I have managed to do it the other way round, but not this way.
I also don't know how I can specify the names of the keys then..
You can use the Gson Library.
List<String> list;
String json = new Gson().toJson(list);
Edited:
Just to have the complete answer here: The problem is that you are converting the json String into a List<String>. This way you are losing the relation key-value. The correct should be convert the json string into a HashMap<>.
It seems like your real problem is that when you originally turned the JSON string into a List, you threw away the keys. And that is not surprising, a List is not a natural representation of a JSON object (i.e. a thing with key - value pairs). You probably should have represented it as a Map.
But anyway, if you threw away the keys you've go a problem. You need to either you change your data structure to not throw the keys away, or reconstruct the JSON by inferring what the keys should be based on (for instance) their position in the list. (The latter could be a bit dodgy because the order of the name/value pairs in the original JSON should not signify anything ... and could be "random" or "implementation dependent".
Lets say that I have a JSON object called fruits and this is the content of it:
"fruits":[{
"name":"natural_one",
"kind"{
0:"apple",
1:"banana",
2:"pear"
}
}];
And when I copy the content of the JSONObject in a new ArrayList, the index order changes like the example here below:
"fruits":[{
"kind"{
1:"banana",
2:"pear",
0:"apple"
},
"name":"natural_one"
}];
What do I do to prevent changing index order when copying content takes place?
I'm not sure this is your problem, but JSON object properties don't have any intrinsic order.
{"a":"b",
"c":"d"}
is strictly equivalent to
{"c":"d",
"a":"b"}
Can someone give me an example how to copy the content of a JSONObject without changing the index order?
It is not possible.
The JSONObject class stores the attributes in a hash table, so is not capable of representing the ordering of the attributes in a serial JSON representation. That's OK because, the JSON spec says that the order of the attributes is not significant.
This comes from the origin of JSON, which is Javascript stntax for associative arrays / objects. The entries in a Javascript associative have no defined / significant order.