Is it possible to have nested array json? - json

I'm kinda new with json. So I want to make an array value inside a value of an array like below.
{
"id": 0,
"title": "LEVEL",
"value": [10[2,3,5], 1]
}
But unfortunately It's not working. It gives me an error when I tried to read the data.
I want to know if it's possible to have an array inside an array value. Thank you.

I always advice people to create a class and generate json from it instead of trying to construct json from your head. It's easier if you do it this way and the generated json will always be valid and exaclty what you wanted.
This is what you want the json to look like:
Here is what the structure should look like:
[Serializable]
public class Dialog
{
public Human human;
public NonHuman nonHuman;
}
[Serializable]
public class Human
{
public Inner inner;
public Outer outer;
}
[Serializable]
public class NonHuman
{
public string val;
}
[Serializable]
public class Inner
{
public string[] val;
}
[Serializable]
public class Outer
{
public string[] val;
}
Now, let's recreate what you have in that screenshot:
//Create new dialog
Dialog dialog = new Dialog();
//Create nonhuman
dialog.nonHuman = new NonHuman();
dialog.nonHuman.val = "Once upon a time...";
//Create human
dialog.human = new Human();
//Create human inner
dialog.human.inner = new Inner();
dialog.human.inner.val = new string[2];
dialog.human.inner.val[0] = "He is so scary";
dialog.human.inner.val[1] = "She is so beautiful";
//Create human outer
dialog.human.outer = new Outer();
dialog.human.outer.val = new string[2];
dialog.human.outer.val[0] = "Hey watch out !";
dialog.human.outer.val[1] = "Look at her har !";
//Convert to Json
string json = JsonUtility.ToJson(dialog);
//Show result in the Console tab
Debug.Log(json);
The generated Json result from Debug.Log:
{"human":{"inner":{"val":["He is so scary","She is so beautiful"]},"outer":{"val":["Hey watch out !","Look at her har !"]}},"nonHuman":{"val":"Once upon a time..."}}
See how I generated the valid json by creating a data structure of what you have in your screenshot, then creating new instance of it. That's the best way to do this. If this is not exactly what you wanted then your image is wrong. You can easily modify the data structure to get what you want.

{
"id": 0,
"title": "LEVEL",
"value": [10, [2, 3, 5], 1]
}
Option2:
{
"id": 0,
"title": "LEVEL",
"value": [10, {
"someKey": [2, 3, 5]
}, 1]
}
Option3:
{
"id": 0,
"title": "LEVEL",
"value": [10, {
"someKey": [2, {
"someKey": [9, 1, 1]
}, 5]
}, 1]
}

Related

Android Kotlin parsing nested JSON

I'm still pretty new to programming with Kotlin but I can't seem to figure out the correct way to parse my JSON. I'm attempting to get "title" and "body" from "notification" in "unackd" array only.
So far I've got:
private fun parse(): Boolean {
try {
val ja = JSONArray(jsonData)
var jo: JSONObject
users.clear()
var user: User
for (i in 0 until ja.length()) {
jo = ja.getJSONObject(i)
val name = jo.getString("title")
val username = jo.getString("body")
user = User(username,name)
users.add(user)
}
return true
} catch (e: JSONException) {
e.printStackTrace()
return false
}
}
Meanwhile my JSON is structured as so:
{
"unackd": [
{
"notification": {
"title": "Title Test Number 200",
"body": "passage local they water difficulty tank industry allow increase itself captured strike immediately type phrase driver change save potatoes stems addition behavior grain trap rapidly love refused way television bright 1100"
},
"data": {
"id": "1100",
"phone": "+15555551234"
}
},
{
"notification": {
"title": "Title Test Number 199",
"body": "announced beside well noted mysterious farm he essential likely deeply vast touch 1099"
},
"data": {
"id": "1099",
"phone": "+15555551234"
}
}
],
"ackd": [
{
"notification": {
"title": "Title Test Number 200",
"body": "passage local they water difficulty tank industry allow increase itself captured strike immediately type phrase driver change save potatoes stems addition behavior grain trap rapidly love refused way television bright 1100"
},
"data": {
"id": "1100",
"phone": "+15555551234"
}
},
{
"notification": {
"title": "Title Test Number 199",
"body": "announced beside well noted mysterious farm he essential likely deeply vast touch 1099"
},
"data": {
"id": "1099",
"phone": "+15555551234"
}
}
]
}
I believe my issue is getting into "notification" to then get the strings "title" and "body". Which I've tried
test1 = jo.getJSONObject("notification")
Any help would be appreciated!
EDIT:
This is my logcat error, I assume it has to do with the JSON.typeMismatch:
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
The exception message suggests that you're passing data that doesn't represent a JSON array when instantiating JSONArray:
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONArray.<init>(JSONArray.java:96)
The JSON you've attached is in fact a JSON object, notice that its content is enclosed in {}. Hence to access the "unackd" array, you need to first create a JSON object, and then reference the array inside of it:
val root = JSONObject(jsonData)
val ja = root.getJSONArray("unackd")
// the rest of your code goes here
Listen friend , parsing the JSON Object with JSON ARRAY with key (like: unackd , ackd) is so simple.
There are 2 ways:
1st Way)
Parse your JSON to Pojo schema
http://www.jsonschema2pojo.org/
public class Ackd {
#SerializedName("notification")
#Expose
private Notification_ notification;
#SerializedName("data")
#Expose
private Data_ data;
public Notification_ getNotification() {
return notification;
}
public void setNotification(Notification_ notification) {
this.notification = notification;
}
public Data_ getData() {
return data;
}
public void setData(Data_ data) {
this.data = data;
}
}
public class Data {
#SerializedName("id")
#Expose
private String id;
#SerializedName("phone")
#Expose
private String phone;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
No need to Make all class for parsing (like ackd (Json Array))
2nd Way)
You need to PARSE JSON array with name only unackd not ackd.
String jsonStr = sh.makeServiceCall(url);
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray unA= jsonObj.getJSONArray("unackd");
for (int i = 0; i < unA.length(); i++)
{
JSONObject c = unA.getJSONObject(i);
String title= c.getString("title");
String body= c.getString("body");
}
Auto generate Data class
http://www.jsonschema2pojo.org/
I suppose that your class is named Response.java
Response object=new Gson().fromjson(jsonContentFile,Response.class);
Following data classes are generated for your JSON using https://json2kotlin.com
data class Json4Kotlin_Base (
val unackd : List<Unackd>,
val ackd : List<Ackd>
)
and
data class Data (
val id : Int,
val phone : Int
)
and
data class Notification (
val title : String,
val body : String
)
and
data class Ackd (
val notification : Notification,
val data : Data
)
and
data class Unackd (
val notification : Notification,
val data : Data
)
Here's a video that explains how to implement these when generated.

How to parse the JSON returned by a REST API call into a collection of objects in JAX-RS?

I am fairly new to JAX-RS so bear with me on this question. I'm trying to consume a REST API using JAX-RS framework. In particular I am trying to invoke a HTTP GET method on a resource where the response entity will be in JSON format. Up until now I can parse the returned JSON into a customized class with the following code snippet;
WebTarget target = client.target(url);
Builder builder = target.request(MediaType.APPLICATION_JSON);
myClass obj = builder.get(myClass.class);
However, in my latest GET request the JSON return will be best abstracted as a collection of objects. I know in .NET this can be done fairly easily with
JsonConvert.DeserializeObject<List<myClass>>
but how could I do that in JAX-RS? Thanks in advance.
EDIT:
I model my code after the solution in How to get list<String> as response from jersey2 client
WebTarget target = client.target(url);
Builder builder = target.request(MediaType.APPLICATION_JSON);
builder.header(X_OCTOPUS_APIKEY_NAME, apiKey);
Response serviceResponse = builder.get(Response.class);
List<myType> objects = serviceResponse.readEntity(new GenericType<List<myType>>() {});
However the objects returned is always null. To verify the REST API call actually return a valid JSON value I replace the last line with:
String strDate = serviceResponse.readEntity(String.class);
It is confirmed with the following JSON return:
[
{
"Id": "Users-267",
"Username": "mdamon#mydomain.com",
"DisplayName": "Damon, Matt",
"IsActive": true,
"IsService": false,
"EmailAddress": "mdamon#mydomain.com",
"IsRequestor": false,
"Links": {
"Self": "/api/users/Users-267",
"Permissions": "/api/users/Users-267/permissions",
"ApiKeys": "/api/users/Users-267/apikeys{/id}{?skip}",
"Avatar": "https://www.gravatar.com/avatar/94324e7c54a9a5f9d103b2a709863fc3?d=blank"
}
},
{
"Id": "Users-2101",
"Username": "baffleck#mydomain.com",
"DisplayName": "Affleck, Ben",
"IsActive": true,
"IsService": false,
"EmailAddress": "baffleck#mydomain.com",
"IsRequestor": false,
"Links": {
"Self": "/api/users/Users-2101",
"Permissions": "/api/users/Users-2101/permissions",
"ApiKeys": "/api/users/Users-2101/apikeys{/id}{?skip}",
"Avatar": "https://www.gravatar.com/avatar/11edd32712facde9a7d3dd4445a4abe9?d=blank"
}
},
...
]
So for reason the JSON is not being parsed at a collection of my custom type. One extra piece of information is my custom is defined as follows:
#XmlRootElement
public class myType {
String DisplayName;
String EmailAddress;
public myType() {
super();
}
public void setDisplayName(String displayName) {
DisplayName = displayName;
}
public String getDisplayName() {
return DisplayName;
}
public void setEmailAddress(String emailAddress) {
EmailAddress = emailAddress;
}
public String getEmailAddress() {
return EmailAddress;
}
}
I only include the DisplayName and EmailAddress field of the JSON in my custom type because I don't need all the other data, in case that matters. Can anyone tell me why it is not being parsed? Thanks

Most efficient way to convert RDD[Status] to specific json

I have a RDD[twitter4j.Status] (from TwitterUtils in Spark API) in my Spark streaming app that I want to convert to this json below, where Id would be (status => status.getId().toString) and Text would be (status => status.getText())
I tried a few things, but I'm not happy with the result and was wondering whether there is a really efficient way to do this.
{
"Inputs": [{
"Id": "1",
"Text": "hello world"
},
{
"Id": "2",
"Text": "hello foo world"
},
{
"Id": "three",
"Text": "hello my world"
}]
}
In the end I created 2 java classes Input and InputsValue and leverage com.google.code.gson:gson:2.6.2 to convert object to Json string.
Why Java classes and not scala ones? Because gson supports List, where T is a custom object, very easily with Java classes compared to spray-io for example. I might be wrong, but that's what I found so far.
public class Input {
public Input(String id, String text) {
this.Id = id;
this.Text = text;
}
public String Id;
public String Text;
}
public class InputsValue {
public InputsValue(List<Input> inputs) {
this.Inputs = inputs;
}
public List<Input> Inputs;
}
val i1 = rdd.map(o => new Input(o.getId().toString, o.getText())).collect().toList;
val iv1: InputsValue = new InputsValue(i1)
val inputs = gson.toJson(iv1)

Deserialize json array and extract value using rest assured

I am a java, json, rest assured newbie and trying to work and learn how to test a rest api. I have an array returned as a rest assured response:
Response response = given(getProjectInfoRequest).get();
response.asString();
{
"options": [
{
"text": "111",
"label": "ABC"
},
{
"text": "222",
"label": "DEF"
},
{
"text": "333",
"label": "GHI"
}
]
}
and I want to extract the value of text say for label value as "DEF", how I can do that?
Please note I have done below so far after reading through so many posts:
1. Options[] options = given(getProjectInfoRequest).when().get().as(Options[].class);
this was giving me exception :
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
then I tried below:
2. Options options = gson.fromJson(response.asString(), Options.getClass());
this at least resolved the above issue.
public class Options {
public String getLabel() {
return label
}
public void setLabel(String label) {
this.label = label
}
public String getValue() {
return value
}
public void setValue(String value) {
this.value = value
}
public String label;
public String value;
}
From this point I am not sure how I can iterate through the array of text and values to extract what I need, please can you guys provide your inputs?
Please pardon my ignorance for asking such a basic question.
Please also suggest me a good source/way to learn this too.
Thanks in advance!
U can use Gson - This is a Java library that can be used to convert Java Objects into their JSON representation.
JsonParser parser = new JsonParser();
JsonObject o = (JsonObject)parser.parse(response.asString());
for (Map.Entry<String,JsonElement> entry : o.entrySet()) {
JsonArray array = entry.getValue().getAsJsonArray();
for (JsonElement elementJSON : array) {
[...]
}
}

How do I specify the root name in a Web Api (JSON) result?

Ive tried the following things and they dont seem to work.
Ember.js Rest Adapter: mapping JSON with no root (.NET Web API)
How can I add a custom root node when serializing an object with JSON.NET?
Im using a web api controller for this.
This is my class and im returning a list of it:
[JsonObject(Title = "rootNamedObject")]
public class RootNamedObject
{
[JsonProperty("ObjectId")]
public int Id { get; set; }
[JsonProperty("Description")]
public string Description { get; set; }
}
Right now this is my result:
[
{
"ObjectId": 1,
"Description": "Description 1",
},
{
"ObjectId": 2,
"Description": "Description 2",
}
]
I need to generate this:
{
"rootNamedObject": [
{
"ObjectId": 1,
"Description": "Description 1"
}
Basically just add the name of the class to the result!
I was having this issue in ember and found the best solution for me was to build a new serializer and override the normalizePayload method. code below:
export default DS.RESTSerializer.extend({
normalizePayload: function(payload) {
var root = "posts";
var output = {};
output[root] = payload;
return output;
} });
This wraps the initial response and adds the root to it, hope it helps!