How I can get "name" under the "language" attribute of this JSONArray? - java

I use a Web-API for a Android App. But I have a problem to get "name" from the attribute "languages".
For the "name" of country I used:
protected String parseJSON(String jsonString) throws Exception {
if (jsonString == null || jsonString.trim().length() == 0) {
return "empty Object";
}
JSONArray jsonarray = new JSONArray(jsonString);
JSONObject jsonObject = jsonarray.getJSONObject(0);
String name = jsonObject.getString("name");
return name;
}
How I can get "name" under the "language" attribute of this JSONArray?
https://restcountries.eu/rest/v2/name/spain

It should be something like this:
JSONArray languages = jsonObject.getJSONArray("languages");
String firstLanguageName = languages.getJSONObject(0).getString("name");
Even though I strongly encourage you using gson instead of parsing this way, gson makes life easier when parsing json.

I use this maven dependency for parsing JSON: https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
Using that, the method you are looking for would be:
protected String parseJSON(String jsonString) throws Exception {
if (jsonString == null || jsonString.trim().length() == 0) {
return "empty Object";
}
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) ((JSONArray) parser.parse(jsonString)).get(0);
JSONObject language = (JSONObject) ((JSONArray) jsonObject.get("languages")).get(0);
return (String) language.get("name");
}
Assuming that you only care about the first language in that json, as the "languages" object is an array.

Related

Java JsonObject from JsonArray

I have Json stored in javax.json.JsonObject, the object look like this:
{
"status":"ok",
"meta":{
"count":2
},
"data":{
"1":{
"id":40,
},
"17":{
"id":48,
}
}
}
How do I access the id key in the sub-object "1" ?
I tried:
obj.getJsonArray("data").getJsonArray("1").getJsonNumber("id").intValue();
However it does not work because the firt call of getJsonArray() method returns a JsonValue object not a JsonObject so the next call of getJsonArray fails. Any ideas ?
You can use an iterator approach to iterate thru the JSONObject:
JSONObject json = new JSONObject(input);
JSONObject jsonData = json.getJSONObject("data");
Iterator<?> jsonDataKeys = jsonData.keys();
while (jsonDataKeys.hasNext()) {
String key = (String)jsonDataKeys.next();
if (jsonData.get(key) instanceof JSONObject) {
System.out.println(((JSONObject) jsonData.get(key)).getInt("id"));
}
}
int id = obj.getJsonObject("data")
.getJsonObject("1")
.getInt("id");
JSONObject jObject = null;
jObject = new JSONObject(String you want to parse);
JSONObject j1Object = jObject.getJSONObject("data");
JSONObject j2Object = j1Object.getJSONObject("1");
String s1=j2Object.getString("id");
System.out.println(s1);

How to modify the JSON data and return the updated JSON data

We have a requirement to update the JSON data in middle and need to return the updated JSON data using java. Also it should support any type of JSON data.
ex:
Assume {object:{"color":"red","shape":"Triangle"}} is the JSON data and in this we need to update the shape value to Rectangle and we need to return the updated JSON data as below:
{object:{"color":"red","shape":"Rectangle"}}
For this we need to pass the element path ( which element we need to update) and updateText and JSON Data to the JAVA code.
here is the methodCall:
updateValue("object/shape", "Rectangle", "{object:{"color":"red","shape":"Triangle"}}")
We tried below code using Gson library. But with this code we are able to update the targeted Json element, but the requirement is to return the entire JSON data with the updated value.
So please suggest how do we re-build the JSON data with the updated text.
Below is the code we tried to update the Json Data.
public String updateValue(String keyPath, String updateText, String jsonText) {
String[] keys = keyPath.split("/");
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = (JsonObject) jsonParser.parse(jsonText);
String result = "";
for(String key : keys)
{
if (jsonObject.get(key) instanceof JsonObject)
{
jsonObject = (JsonObject)jsonObject.get(key);
}
else if(jsonObject.get(key) instanceof JsonArray)
{
JsonArray jsonArray = (JsonArray)jsonObject.get(key);
result = jsonArray.toString();
}
else
{
result = jsonObject.get(key).toString();
}
}
result = result.replace(result, updateText);
return result;
}
The problem lies in the way you do the replacements. When you translate the JsonObject to String, you lose the object, and after replacement, you just have the replaced String. To fix it, you need to operate directly on the object, instead of the String counterpart. Because JsonObject is mutable, holding a reference to the input will reflect the changes. One drawback is you can't replace a value in a JsonArray this way, partly because you don't know which element to replace. To accomplish that, you will need a little more in the input(either the value to replace or the element position).
public String updateValue(String keyPath, String updateText, String jsonText) {
String[] keys = keyPath.split("/");
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = (JsonObject) jsonParser.parse(jsonText);
JsonObject returnVal = jsonObject; // This holds the ref to target json object
JsonPrimitive jp = new JsonPrimitive(updateText);
String finalKey = keys[keys.length - 1];
for(String key : keys)
{
if (jsonObject.get(key).isJsonObject())
{
jsonObject = (JsonObject)jsonObject.get(key);
}
}
jsonObject.remove(finalKey);
jsonObject.add(finalKey, jp);
return returnVal.toString();
}
You can use JsonPath lib for that and try using the following code.
private static final Configuration configuration = Configuration.builder()
.jsonProvider(new JacksonJsonNodeJsonProvider())
.mappingProvider(new JacksonMappingProvider())
.build();
JsonNode updatedJson = JsonPath.using(configuration).parse(originaljson)
.set("use the path to go for value", "new value").json();
json = updatedJson.toString();

Convert JSON String to JSON Array

Hello i call a service if it contains multiple objects it make list but when it contain only one object it return a single object not a list [] are missing , actually i want to convert them into java class using gson but in case of single exception it throw exception but when it contain list it work fine i actually need to convert my single gSON string to array ,please help me ..here is the string
{
"response":{
"projects":{
"project":{
"ixWorkflow":1,
"sEmail":"j.a#loxvo.com",
"sPhone":"",
"ixProject":2,
"ixPersonOwner":2,
"fDeleted":false,
"sProject":"Project Default",
"fInbox":true,
"sPersonOwner":"junaid"
}
}
}
}
i want it to be like same as
{
"response":{
"projects":{
"project":[
{
"ixWorkflow":1,
"sEmail":"j.a#loxvo.com",
"sPhone":"",
"ixProject":6,
"ixPersonOwner":2,
"fDeleted":false,
"sProject":"project 2",
"fInbox":false,
"sPersonOwner":"junaid"
},
{
"ixWorkflow":1,
"sEmail":"j.a#loxvo.com",
"sPhone":"",
"ixProject":2,
"ixPersonOwner":2,
"fDeleted":false,
"sProject":"Project Default",
"fInbox":true,
"sPersonOwner":"junaid"
}
]
}
}
}
With reference to https://stackoverflow.com/a/7284813/1105291
Please try below code before you pass json to Gson for object conversion, and please let me know if you get any error. Only posibility that I can see is exception at if.
JSONObject jsonObject = new JSONObject(responseString);
JSONObject projectsJsonObject = jsonObject.getJSONObject("response").getJSONObject("projects");
if(projectsJsonObject.getJSONArray("project") == null)
{
JSONArray jsonArray = new JSONArray();
jsonArray.put(projectsJsonObject.getJSONObject("project"));
projectsJsonObject.put("project", jsonArray);
}
//Pass jsonObject to Gson
Use Google Gson
JsonParser parser = new JsonParser();
JsonObject o = (JsonObject)parser.parse("{\"a\": \"A\"}");

JSON Object is null while parsing

The format of my json object is:
String jsonObjRecv = {
"response":{
"respobj":{
"id":<int>,
"number":<string>,
"validated":<boolean>
}
},
"status":"ok",
"errors":null
}
It works when code is:
JSONObject jsonObjCont = new JSONObject(jsonObjRecv);
String getString= jsonObjCont.toString(2);
In this case getString != null and I can receive data, but when I try to get nested data of JSON object as like:
JSONObject jsonObjCont = new JSONObject(jsonObjRecv);
JSONObject regNumber = jsonObjCont.getJSONObject("respobj");
String number= regNumber.getString("number");
it dont work.
I tried to use GSON library, but it works when:
public String parse(String jsonObjRecv) {
JsonElement jelement = new JsonParser().parse(jsonObjRecv);
String result = jelement.toString();
return result;
and don't work :
public String parse(String jsonObjRecv) {
JsonElement jelement = new JsonParser().parse(jsonObjRecv);
JsonObject jobject = jelement.getAsJsonObject();
jobject = jobject.getAsJsonObject("respobj");
String result = jobject.get("number").toString();
return result;
Where is my mistake?
The problem is you're not accessing your JSON object correctly - it's an object that contains a response object which contains a respobj object.
Gson example follows. Note the comment in the code - you need to get the response object then get the respobj from it.
public static void main( String[] args )
{
String jsonObjRecv = "{\"response\":{\"respobj\":{\"id\":1,\"number\":\"22\",\"validated\":true}},\"status\":\"ok\",\"errors\":null}";
JsonElement jelement = new JsonParser().parse(jsonObjRecv);
JsonObject jobject = jelement.getAsJsonObject();
// Here is where you're making an error. You need to get the outer
// 'response' object first, then get 'respobj' from that.
jobject = jobject.getAsJsonObject("response").getAsJsonObject("respobj");
String result = jobject.get("number").getAsString();
System.out.println(result);
}
Output:
22
Edit to add: Note I used getAsString() vs. toString() - if you use the latter you get the raw JSON which will incluse the quotes around the value (e.g. the output would be "22")

Test if it is JSONObject or JSONArray

I have a json stream which can be something like :
{"intervention":
{
"id":"3",
"subject":"dddd",
"details":"dddd",
"beginDate":"2012-03-08T00:00:00+01:00",
"endDate":"2012-03-18T00:00:00+01:00",
"campus":
{
"id":"2",
"name":"paris"
}
}
}
or something like
{"intervention":
[{
"id":"1",
"subject":"android",
"details":"test",
"beginDate":"2012-03-26T00:00:00+02:00",
"endDate":"2012-04-09T00:00:00+02:00",
"campus":{
"id":"1",
"name":"lille"
}
},
{
"id":"2",
"subject":"lozlzozlo",
"details":"xxx",
"beginDate":"2012-03-14T00:00:00+01:00",
"endDate":"2012-03-18T00:00:00+01:00",
"campus":{
"id":"1",
"name":"lille"
}
}]
}
In my Java code I do the following:
JSONObject json = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream
JSONArray interventionJsonArray = json.getJSONArray("intervention");
In the first case, the above doesn't work because there is only one element in the stream..
How do I check if the stream is an object or an array ?
I tried with json.length() but it didn't work..
Thanks
Something like this should do it:
JSONObject json;
Object intervention;
JSONArray interventionJsonArray;
JSONObject interventionObject;
json = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream
Object intervention = json.get("intervention");
if (intervention instanceof JSONArray) {
// It's an array
interventionJsonArray = (JSONArray)intervention;
}
else if (intervention instanceof JSONObject) {
// It's an object
interventionObject = (JSONObject)intervention;
}
else {
// It's something else, like a string or number
}
This has the advantage of getting the property value from the main JSONObject just once. Since getting the property value involves walking a hash tree or similar, that's useful for performance (for what it's worth).
Maybe a check like this?
JSONObject intervention = json.optJSONObject("intervention");
This returns a JSONObject or null if the intervention object is not a JSON object. Next, do this:
JSONArray interventions;
if(intervention == null)
interventions=jsonObject.optJSONArray("intervention");
This will return you an array if it's a valid JSONArray or else it will give null.
To make it simple, you can just check first string from server result.
String result = EntityUtils.toString(httpResponse.getEntity()); //this function produce JSON
String firstChar = String.valueOf(result.charAt(0));
if (firstChar.equalsIgnoreCase("[")) {
//json array
}else{
//json object
}
This trick is just based on String of JSON format {foo : "bar"} (object)
or [ {foo : "bar"}, {foo: "bar2"} ] (array)
You can get the Object of the input string by using below code.
String data = "{ ... }";
Object json = new JSONTokener(data).nextValue();
if (json instanceof JSONObject)
//do something for JSONObject
else if (json instanceof JSONArray)
//do something for JSONArray
Link: https://developer.android.com/reference/org/json/JSONTokener#nextValue
Object valueObj = uiJSON.get(keyValue);
if (valueObj instanceof JSONObject) {
this.parseJSON((JSONObject) valueObj);
} else if (valueObj instanceof JSONArray) {
this.parseJSONArray((JSONArray) valueObj);
} else if(keyValue.equalsIgnoreCase("type")) {
this.addFlagKey((String) valueObj);
}
// ITERATE JSONARRAY
private void parseJSONArray(JSONArray jsonArray) throws JSONException {
for (Iterator iterator = jsonArray.iterator(); iterator.hasNext();) {
JSONObject object = (JSONObject) iterator.next();
this.parseJSON(object);
}
}
I haven't tryied it, but maybe...
JsonObject jRoot = RestManager.getJSONfromURL(myuri); // retrieve the entire json stream
JsonElement interventionElement = jRoot.get("intervention");
JsonArray interventionList = new JsonArray();
if(interventionElement.isJsonArray()) interventionList.addAll(interventionElement.getAsJsonArray());
else interventionList.add(interventionElement);
If it's a JsonArray object, just use getAsJsonArray() to cast it. If not, it's a single element so just add it.
Anyway, your first exemple is broken, you should ask server's owner to fix it. A JSON data structure must be consistent. It's not just because sometime intervention comes with only 1 element that it doesn't need to be an array. If it has only 1 element, it will be an array of only 1 element, but still must be an array, so that clients can parse it using always the same schema.
//returns boolean as true if it is JSONObject else returns boolean false
public static boolean returnBooleanBasedOnJsonObject(Object jsonVal){
boolean h = false;
try {
JSONObject j1=(JSONObject)jsonVal;
h=true;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
if(e.toString().contains("org.json.simple.JSONArray cannot be cast to org.json.simple.JSONObject")){
h=false;
}
}
return h;
}

Categories