Show JSON data in grid in vaadin - java

Am a new bee to vaadin. I have to show the data from a JSON file (which is fetching from MySQL db) in Grid/Table(vaadin). I am able show the data in table if JSON in the below format.
[
{
"id": "ex-wardrobe",
"productId": "ex-wardrobe",
"name": "exWardrobe",
"desc": "Some description",
"dimension": "WxDxH 148\" X 24\" X 112\" ",
"category": "Bedroom",
"subcategory": "Wardrobe",
"categoryId": "bedroom",
"subcategoryId": "wardrobe",
"tags": "all, Space Design Bedroom, Space Details Wardrobe",
"designer": "hb",
"curr": "INR",
"popularity": "1",
"relevance": "1",
"shortlisted": "1",
"likes": "1",
"createDt": "",
"pageId": "ex-wardrobe",
"styleName": "Fresh",
"styleId": "cfresh",
"priceRange": "Premium",
"priceId": "premium",
"defaultPrice": "123",
"defaultMaterial": "MDF ",
"defaultFinish": "LAMINATE"
}
]
But, if i get JSON(data is related to same product) in the below format am unable to add data in table.
[
{
"id": "ex-wardrobe",
"productId": "ex-wardrobe",
"name": "exWardrobe",
"desc": "Some description",
"dimension": "WxDxH 148\" X 24\" X 112\" ",
"category": "Bedroom",
"subcategory": "Wardrobe",
"categoryId": "bedroom",
"subcategoryId": "wardrobe",
"tags": "all, Space Design Bedroom, Space Details Wardrobe",
"designer": "hb",
"curr": "INR",
"popularity": "1",
"relevance": "1",
"shortlisted": "1",
"likes": "1",
"createDt": "",
"pageId": "ex-wardrobe",
"styleName": "Fresh",
"styleId": "cfresh",
"priceRange": "Premium",
"priceId": "premium",
"defaultPrice": "123",
"defaultMaterial": "MDF ",
"defaultFinish": "LAMINATE",
"mf": [
{
"basePrice": "123",
"material": "MDF ",
"finish": "LAMINATE"
}
],
"images": [
"066___ex_WARDROBE_Dim.jpg",
"067___ex_WARDROBE_close_door.jpg",
"068___ex_DOVE_dim.jpg"
],
"components": [],
"accessories": []
}
]
This is the code which am using to show JSON data in table,
Table grid = new Table();
root.addComponent(grid);
grid.setStyleName("iso3166");
grid.setPageLength(6);
grid.setSizeFull();
grid.setSelectable(true);
grid.setMultiSelect(false);
grid.setImmediate(true);
grid.setColumnReorderingAllowed(true);
grid.setColumnCollapsingAllowed(true);
try {
JSONArray products = productsDataProvider.getCatalogs();
JsonContainer dataSource =
JsonContainer.Factory.newInstance(products.toString());
grid.setContainerDataSource(dataSource);
grid.setColumnReorderingAllowed(true);
grid.setWidth("98%");
grid.addStyleName(ChameleonTheme.TABLE_STRIPED);
} catch (IllegalArgumentException ignored) {
}
grid.setWidth("100%");
grid.setHeight("100%");
root.addComponent(grid);
Am stuck on this and i have sleepless night on this. Million tons of thanks in advance. I hope you GURU's can help me in this :)

Sorry not vaadin expert. See it first time and like it. I guess your problem are the arrays inside your object. I mean this:
"mf": [
{
"basePrice": "173881",
"material": "MDF ",
"finish": "LAMINATE"
}
],
"images": [
"066___ex_WARDROBE_Dim.jpg",
"067___ex_WARDROBE_close_door.jpg",
"068___ex_DOVE_dim.jpg"
],
"components": [],
"accessories": []
No idea how the component should display this. Have you tried it without mf, images, components and accessories?

You are using a very simple JSONContainer. As can be seen in the source code, this implementation does not support nested / compound elements and arrays.
First you have to ask yourself how these complex objects need to be displayed (UX), especially the "mf" field.
UPDATE
Simple compound objects (like "simpleCompound": {"name": "foo", number: 123}) can be shown in a table column (not supported by the JSONContainer you use, but similar functionality is available by the BeanItemContainer, so look there for how to implement this functionality).
The array fields are more problematic from a UX standpoint. Mostly this information is only shown on demand or in separate panels. The Vaadin Grid component offers the possibility to show a details view, see the wiki. Maybe that will fit your requirements.

Currently nested json data is not supported unless you create your own advance template for that. There is currently an online json container application demo that is used to test if the data is really json or json array but not nested. Then it displays that data in grid table. So you can use this to verify your data.
You can also get the application template with source code on github

Related

How can I store and update the nested json object into couchbase using java sdk

I am using couchbase Community Edition 5.0.1 and java-client 2.7.4. I want to store the following nested json object into couchbase. If I want to update the same object without affecting the other fields.
Eg:
If I want to add one more player object under players object
array
If I want to add One more group say 'Z Group' under group object array
How can I Achieve this without affecting other fields.
{
"doctype": "config:sample",
"group": [{
"name": "X Group",
"id": 1,
"players": [{
"name": "Roger Federer",
"number": 3286,
"keyword": "tennies"
},
{
"name": "P. V. Sindhu",
"number": 4723,
"keyword": "badminton"
}
]
},
{
"name": "Y Group",
"id": "2",
"players": [{
"name": "Jimmy Connors",
"number": 5623,
"keyword": "tennies"
},
{
"name": "Sachin",
"number": 8756,
"keyword": "Cricket"
}
]
}
]
}
N1QL has a huge variety of functions to operate on arrays:
https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/arrayfun.html
In your case, you could simply use ARRAY_INSERT or ARRAY_PREPEND
Check out update/update-for syntax (last example) https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/update.html
UPDATE default AS d
SET d.group = ARRAY_APPEND(d.group, {......})
WHERE .....;
UPDATE default AS d
SET g.players = ARRAY_APPEND(g.players, {......}) FOR g IN d.group WHEN g.id = 2 END
WHERE .....;
If you know which document IDs you want to update you can use the key-value subdocument API, which will generally be faster than going via N1QL for a single document update.
This will add a new player to the end of X Group's "players" array:
bucket.mutateIn(docId)
.arrayAppend("group[0].players",
JsonObject.create()
.put("name", "John Smith"))
// ... other player JSON
.execute();
And this will add a new Group Z to the "group" array:
bucket.mutateIn(docId)
.arrayAppend("group",
JsonObject.create()
.put("name", "Z Group"))
// ... other group JSON
.execute();

Parsing JSON array in Java

I'm currently parsing a JSON file to my Java Program and I ecounter a problem.
I get a JSON array that can look like this for example:
[
{
"itemType": "magazineArticle",
"creators": [
{
"firstName": "J. Antonio",
"lastName": "Garcia-Macias",
"creatorType": "author"
},
{
"firstName": "Jorge",
"lastName": "Alvarez-Lozano",
"creatorType": "author"
},
{
"firstName": "Paul",
"lastName": "Estrada-Martinez",
"creatorType": "author"
},
{
"firstName": "Edgardo",
"lastName": "Aviles-Lopez",
"creatorType": "author"
}
],
"notes": [],
"tags": [],
"title": "Browsing the Internet of Things with Sentient Visors",
"publicationTitle": "Computer",
"volume": "44",
"issue": "5",
"ISSN": "0018-9162",
"date": "2011",
"pages": "46-52",
"abstractNote": "Unlike the traditional Internet, the emerging Internet of Things constitutes a mix of virtual and physical entities. A proposed IoT browser enables the exploration of augmented spaces by identifying smart objects, discovering any services they might provide, and interacting with them.",
"extra": "CICESE Research Center, Mexico; CICESE Research Center, Mexico; CICESE Research Center, Mexico; CICESE Research Center, Mexico",
"libraryCatalog": "IEEE Computer Society"
}
]
The problem is I have to do a check each time I parse if the field called "extra" is in the array, since it's not included every time i parse.
So how do I do that check to see if the field "extra" exists?
Without framework, you can use JSONObject and JSONArray from org.json.*. Here is an example (not tested). It will allows you to check if the extra key is present
String jsonAsString = "/*Your json as a String*/";
JsonArray jsonArray = new JSONArray(jsonAsString);
for(int i=0; i<jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
//Get values from your jsonObject
jsonObject.has("extra"); //Check if extra is present
}
Use "has" method of JSONObject like this:
Array.getJSONObject(j).has("extra")

Most memory efficient way to re format a JSON array in Java

Say I have a JSON array similar to the following:
[
{
"title": "This is a title",
"year": 2013,
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
"thumbsdown": 256
}
},
{
"title": "This is a title",
"year": 2013,
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
"thumbsdown": 256
}
}
]
And the required output is a JSON array like this:
[
{
"title": "This is a title",
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
}
},
{
"title": "This is a title",
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
}
}
]
Iv'e been researching and it's suggested that the most efficient way would be to parse it using the Jackson streaming API. This is for use on a PaaS with limited memory, so I wish to keep the memory usage to the bare minimum.
Is the best way to parse the JSON with Jackson Streaming API, and construct a new JSON array at the same time or simply remove the elements somehow?
I did something similiar with XML once. You can have the requestor tell you what fields you want to get back, and have it only emit those. In my case I had no control over the 3rd party axis xml view, but once I had the view, when I asked for things from it if it was already there I could give back just the pieces I was interested in. As a bonus, if you are marshalling or unmarshalling real java objects from the JSON after getting the json or XML you don't need to build the part of the object graph you don't care about.

how to read data from json url in java?

I came across the following tutorial:
http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
But this tutorial shows how to convert json to a Java object , when the json file is stored on the user's pc.
What I want to do is, when I go to the following link:
http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=[MyApiKey]&q=Toy+Story+3&page_limit=1
it returns me the following json data:
{
"total": 2,
"movies": [{
"id": "770672122",
"title": "Toy Story 3",
"year": 2010,
"mpaa_rating": "G",
"runtime": 103,
"critics_consensus": "Deftly blending comedy, adventure, and honest emotion, Toy Story 3 is a rare second sequel that really works.",
"release_dates": {
"theater": "2010-06-18",
"dvd": "2010-11-02"
},
"ratings": {
"critics_rating": "Certified Fresh",
"critics_score": 99,
"audience_rating": "Upright",
"audience_score": 91
},
"synopsis": "Pixar returns to their first success with Toy Story 3. The movie begins with Andy leaving for college and donating his beloved toys -- including Woody (Tom Hanks) and Buzz (Tim Allen) -- to a daycare. While the crew meets new friends, including Ken (Michael Keaton), they soon grow to hate their new surroundings and plan an escape. The film was directed by Lee Unkrich from a script co-authored by Little Miss Sunshine scribe Michael Arndt. ~ Perry Seibert, Rovi",
"posters": {
"thumbnail": "http://content6.flixster.com/movie/11/13/43/11134356_mob.jpg",
"profile": "http://content6.flixster.com/movie/11/13/43/11134356_pro.jpg",
"detailed": "http://content6.flixster.com/movie/11/13/43/11134356_det.jpg",
"original": "http://content6.flixster.com/movie/11/13/43/11134356_ori.jpg"
},
"abridged_cast": [
{
"name": "Tom Hanks",
"characters": ["Woody"]
},
{
"name": "Tim Allen",
"characters": ["Buzz Lightyear"]
},
{
"name": "Joan Cusack",
"characters": ["Jessie the Cowgirl"]
},
{
"name": "Don Rickles",
"characters": ["Mr. Potato Head"]
},
{
"name": "Wallace Shawn",
"characters": ["Rex"]
}
],
"alternate_ids": {"imdb": "0435761"},
"links": {
"self": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122.json",
"alternate": "http://www.rottentomatoes.com/m/toy_story_3/",
"cast": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/cast.json",
"clips": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/clips.json",
"reviews": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/reviews.json",
"similar": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json"
}
}],
"links": {
"self": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=Toy+Story+3&page_limit=1&page=1",
"next": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=Toy+Story+3&page_limit=1&page=2"
},
"link_template": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q={search-term}&page_limit={results-per-page}&page={page-number}"
}
I want to store this data in a Java Object and then use it. I am a newbie in Java programming.
Thanks.
I would suggest to use something like Gson library, for parsing the Json.
Gson makes it quite elegant and simple.
However, as you are new, I would suggest you to go through the Gson Overview.
Jackson has some built-in methods to read from URLs. You can try the following (using java.net.URL):
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(new URL("http://www.mydomain.com/info.json"), User.class);

Displaying JSON in a ListView with separators

I want to be able to take the JSON data and format it into a ListView with each of the outermost objects as the headings. For example, there should be a divider for "Company A" and all of its projects under the divider. Then there should be the "Company B" divider and it's project under that header. Here's an example of a JSON response I'll be working with. I know how to parse the JSON, just not how to display it.
{
"Company A": {
"name": "Company A",
"id": "1145",
"projects": [
{
"name": "Test Project - DELETE",
"id": "39771",
"amount": "0.00",
"billingType": "HOURLY",
"date": "2012-07-09 15:38:06",
"u_id": "25445",
"itemID": "3"
},
{
"name": "TEST",
"id": "39905",
"amount": "0.00",
"billingType": "FIXED",
"date": "2012-07-10 13:19:10",
"u_id": "25455",
"itemID": "1"
},
{
"name": "Test Project - DELETE",
"id": "39771",
"amount": "0.00",
"billingType": "HOURLY",
"date": "2012-07-09 15:38:06",
"u_id": "25445",
"itemID": "4"
}
]
},
"Company B": {
"name": "Company B",
"id": "5569",
"projects": [
{
"name": "Type Test",
"id": "39657",
"amount": "0.00",
"billingType": "FIXED",
"date": "2012-07-12 10:14:30",
"u_id": "25479",
"itemID": "1"
}
]
}
}
Is there an easy way to achieve this kind of formatting?
Yes and no.
You can easily convert each set (header with content) into an object, and the content itself into sub-objects (if you need help, ask :)); the hard part is configuring the ListView if you aren't familiar with using multiple item types.
I think the answer to this question will be of use to you.
To summarize: basically, ListView can be made to use multiple item types; so your header would be one item type and each data item would be of a second type. Just implement the glue logic so that you get the right view type for the right object, and the right object for the right ListView "position".

Categories

Resources