Salaam,
Using json.org API, we can easily convert a map to a JSON object :
Map<String, String> carta = new Map<String, String>();
carta.put( "id", "123");
carta.put( "Planet", "Earth");
carta.put( "Status", "getting dirty");
JSONObject json = new JSONObject();
for(Iterator<String> it=input.keySet().iterator(); it.hasNext();){
String key = it.next();
json.put(key, input.get(key));
}
System.out.println(json.toString());
// output: {id:"123", Planet:"Earth", Status: "getting dirty"}
Now we want to have an array of these object
The API doesn't provide this does it?
At least, adding JSONObjects to a JSONArray removes the brackets :
JSONArray joArr = new JSONArray();
joArr.put( cartaEarth );
joArr.put( cartaMars );
System.out.println( joArr.toString() );
//output: [{ id:123, Planet:Earth, Status: getting dirty }, {id: 456, Planet:Mars, Status: maybe aliens there }]
without brackets...while in the API they mention:
put(java.util.Map value)
Put a value in the JSONArray, where the value will be a JSONObject which is produced from a Map.
instead of doing it byhand, preferred to discuss it first, thanks in advance!
have you try GSon ? it is specialized in Java Object to JSon and Json to Java Object.
I would recommend looking at something else than org.json package. Pretty much all alternatives from org.json list provide more convenient and simpler ways to work with JSON.
Aside from Gson that some like, I would recommend Jackson; and flex-json and Svenson are other packages that seem decent.
If you insist on doing this using org.json, you need to explain your problem bit more -- API has all the methods you need, and they do allow you to add values of all types (JSON arrays, objects, strings, numbers, booleans and nulls). But your types need to match JSON types, so there are no conversions from arrays to objects, for example.
Related
I am a novice in java and I am looking for a way to know if a json object contains another jsonObject by using json.org library (not json.org.simple).
For the moment I am using this :
JSONObject json= new JSONObject();
json.has("JsonFieldName");
but but I need to know if there is a way to not specify the Json field Name
If you have a better solution with Json.org, I will take.
Thanks
You can get an Iterator for all the keys in the object from keys, and loop through them seeing if any of the values for the keys is a JSONObject (as opposed to a JSONArray or primitive).
for (String key : json.keys()) {
if (json.get(key) instanceof JSONObject) {
// Yes, it contains at least one JSONObject, whose key is `key`
}
}
I am searching a good and dynamic way to parse JSON in Java.
I've seen things such as:
List<String> list = new ArrayList<String>();
JSONArray array = obj.getJSONArray("test");
for(int i = 0 ; i < array.length() ; i++){
list.add(array.getJSONObject(i).getString("testKey"));
}
But that's not what I'm searching. In C# I had something like that:
dynamic results = JsonConvert.DeserializeObject<dynamic>(json);
info.Text = results["test"]["testKey"];
Here's an example of my JSON:
{"date":"07.05.2017 11:44",
"monday":{"1":{"subject":"test","room":"test","status":"test"}}}
So for example I would like to make:
results["monday"]["1"]["subject"];
I hope someone understands my problem and can help me.
Thanks in advance!
The core Java runtime does not offer a JSON parser (edit: technically, it does, see bottom of answer), so you will need a library. See Jackson, Gson, perhaps others.
Even with that, you will not get the dynamic features you want, because Java is statically typed. Example with Jackson:
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>(){});
map.get("monday").get("1").get("subject");
^^^
This fails because the result of get("monday") is Object, not Map
The "right" approach in Java-land, would be to create a class (or set of classes) that represents your JSON model, and pass it to the JSON parser's "object mapper". But you said "dynamic" so I'm not exploring this here.
So you'll need to cast to Map when you know it's not primitive values:
((Map<String,Map<String,String>>)map.get("monday")).get("1").get("subject");
This works but with a warning about unchecked cast...
All in all, Java is not a dynamic language and I see no way to do exactly what you want (perhaps I'm missing approaches that are still slightly easier than what I have suggested).
Are you limited to Java-the-language or Java-the-platform? In the latter case you can use a dynamic language for the Java platform, such as Groovy, who has excellent features to parse JSON.
EDIT: a funny alternative is to use Java's own JavaScript implementation. This works and is easy and dynamic, but I don't know if it's "good":
String json = "{\"date\":\"07.05.2017 11:44\",\n" +
"\"monday\":{\"1\":{\"subject\":\"test\",\"room\":\"test\",\"status\":\"test\"}}}";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.put("data", json);
System.out.println(engine.eval("JSON.parse(data)['monday']['1']['subject']"));
If you are sure about the value you want to get then you can do following as well :
String str = "{\"date\":\"07.05.2017 11:44\", \"monday\":{\"1\":{\"subject\":\"test\",\"room\":\"test\",\"status\":\"test\"}}}";
JSONObject results= new JSONObject(str);
String str1 = results.getJSONObject("monday").getJSONObject("1").getString("subject");
System.out.println(str1);
For array kind of results, we have to write logic for that. In this case org.json library is used.
You can use GCON library:
https://github.com/google/gson
Very good for parsing JSON objects.
I have an API request from my CRM that can either return a jsonObject if there is only one result, or a jsonArray if there are multiple results. Here are what they look like in JSON Viewer
JsonObject:
JsonArray:
Before you answer, this is not my design, it's my CRM's design, I don't have any control over it, and yes, I don't like how it is designed either. The only reason I am not storing the records in my own database and just parsing that, which would be MUCH easier, is because my account is having issues not running some workflows that would allow me to auto add the records. Is there any way to figure out if the result is an object or an array using java? This is for an android app by the way, I need it to display the records on the phone.
You should use OPT command instead of GET
JSONObject potentialObject=response.getJsonObject("resuslt")
.getJsonObject("Potentials");
// here use opt. if the object is null, it means its not the type you specified
JSONObject row=potentialObject.optJsonObject("row");
if(row==null){
// row is json array .
JSONArray rowArray=potentialObject.getJsonArray("row");
// do whatever you like with rowArray
} else {
// row is json object. do whatever you like with it
}
ONE
You can use instanceof keyword to check the instances as in
if(json instanceof JSONObject){
System.out.println("object");
}else
System.out.println("array");
TWO
BUT I think a better way to do this is choose to use only JSONArray so that the format of your results can be predicated and catered for. JSONArrays can contain JSONObjects. That is they can cover the scope of JSONObject.
For example when you get the response (either in a JSONObject or a JSONArray), you need to store that in an instance. What instance are you going to store it in? So to avoid issues use JSONArray to store the response and provide statements to handle that.
THREE
Also you can try method overloading in java or Generics
Simplest way is to use Moshi, so that you dont have to parse, even in the case of the Model changing later, you have to change your pojo and it will work.
Here is the snippet from readme
String json = ...;
Moshi moshi = new Moshi.Builder().build();
JsonAdapter<BlackjackHand> jsonAdapter = moshi.adapter(BlackjackHand.class);
BlackjackHand blackjackHand = jsonAdapter.fromJson(json);
System.out.println(blackjackHand);
https://github.com/square/moshi/blob/master/README.md
I am having an Java Object which consist many type of variables including a JSONObject.
Whan i debug my object i got the following String for JSONObject:-
{"INCLUSIONS":{"OPTIONS":[{"display":"Complimentary stay for children under 5 without extra bed"}]}}
But when i used:-gson.toJson(JSONObj),I got following
{"myHashMap":{"INCLUSIONS":{"myHashMap":{"OPTIONS":{"myArrayList":[{"myHashMap":{"display":"Complimentary stay for children under 5 without extra bed"}}]}}}}}
Someone please can elaborate why it is converting JSONObject to Map & list ??
Or Any work Around ??
Thanks.
Just use myJsonObj.toString() instead of myJsonObj.toJSON()
Your problem happens because a JSONObject is stored as a HashMap to allow the programmer to reach values with methods based on keys. As example,
String jsonStr = "{'key': 'value'}";
JsonObject json = gson.fromJson(jsonStr, JsonObject.class);
String value = json.get("key").getAsString();
You can figure that json attributes are stored as a HashMap<JsonElement>
When Parsing JSON I normally just constuct an object and use the gsonlibrary to parse my String into that object.
However, I now find myself with a rather complex response which consists of many elements each with sub elements of objects and arrays and arrays of objects. It looks something like this...
{
"type": "thetype",
"object":{
"text": "texthere",
"moretext": "more here"
},
...,
...,
...,
...,
"fieldIwant": [
{
"object":"object!"
},
....
....
{
"object":"object!"
},
]
}
The thing is, I'm only really interested in fieldIwantand nothing else. Is there not a way in Java for me to just extract that field and work with it alone and not all this other dead weight I do not need?
According to this http://sites.google.com/site/gson/gson-design-document it looks like gson does this for you by default.
When you are deserializing a Json string into an object of desired type, you can either navigate the tree of the input, or the type tree of the desired type. Gson uses the latter approach of navigating the type of the target object. This keeps you in tight control of instantiating only the type of objects that you are expecting (essentially validating the input against the expected "schema"). By doing this, you also ignore any extra fields that the Json input has but were not expected.
In other words, it doesn't deserialize any of the fields you don't need. You should be good to go.
You can use the low level JsonParser API
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
yourArray = new Gson().fromJson(jsonObject.get("fieldIwant"), yourArrayType);
Alternatively you can create an ExclusionStrategy to use with a GsonBuilder