How to get list of objects from JSON ??

439 views
Skip to first unread message

Santosh kumar

unread,
Oct 23, 2010, 1:38:22 AM10/23/10
to google-we...@googlegroups.com
Hi,

Using Dictionary in Gwt onModule load i want to get the list of objects from Json  ???

http://code.google.com/webtoolkit/articles/dynamic_host_page.html

The example in the above link it is shown for string, but i want to get the list of objects form the json ??
And also can you send me the sample code of JSON format for the list of objects(same as shown in the above example)
and also how to retrieve these objects in the gwt using Dictionary ?

please can anyone guide me ?

--
Thanks & Regards

S a n t o s h  k u m a r . k

Thomas Broyer

unread,
Oct 23, 2010, 6:07:12 AM10/23/10
to Google Web Toolkit
Use JSNI instead (Dictionary, as its name and package imply, is
designed for i18n, getting string constants from keys).
http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html

public static native JsArray<Foo> getListOfFoo() /*-{ return
$wnd.myVariable.foo; }-*/;

(where Foo is a JavaScript Overlay type:
http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsOverlay.html
)

Subhrajyoti Moitra

unread,
Oct 23, 2010, 9:51:41 AM10/23/10
to google-we...@googlegroups.com
http://googlewebtoolkit.blogspot.com/2008/08/getting-to-really-know-gwt-part-2.htm

Use overlay types to read JSON arrays and objects.

Thanks,
Subhro.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Santosh kumar

unread,
Oct 26, 2010, 9:38:34 AM10/26/10
to google-we...@googlegroups.com
Hi ,

Moitra
and Thomas

Thanks for your reply.. !!
 
Anyways i got a solution..

use this code in the servlet ---
- get the list of products (productList) and use it in the servlet:
- This is JSON format to form a array of objects

        // Open the <script> tag
        writer.append("<script type=\"text/javascript\">");
        writer.append("var product=");
        writer.append("{productList: '[");
       
        Iterator<Product> iter = productList.iterator();
        while (iter.hasNext()) {
            Product product= iter.next();
            writer.append("{productName: \"" + Product .getProductName() +
                    "\", id: " + Product .getId() +
                    ", productDetails: \"" + Product .getProductDetails() +
                       .................................
                       ................................. 
                      "\"}");
            if (iter.hasNext()) {
                writer.append(",");
            }
        }
       
        // End the <script> tag
        writer.append("]'}; </script>");


use this code in the GWT onModule ---
- call the above servlet on onModule

        Dictionary product= Dictionary.getDictionary("product");
        String productListStr = product.get("productList").toString();
        JSONArray productJSONArray = JSONParser.parse(productListStr ).isArray();
        List<Product> ProductList = new ArrayList<Product>();
        for (int i = 0; i < productJSONArray .size(); i++) {
            JSONObject productJSONObject = (JSONObject)productJSONArray .get(i);
            Product product= new Product();
           
            JSONString productNameJSONString = productJSONObject .get("productName").isString();
            product.setProductName(productNameJSONString .stringValue());
           
            product.setId(Long.valueOf(productJSONObject .get("id").toString()));
           
            .........................
            .........................
            
            ProductList .add(product);
        }

finally we will get a list of objects. i.e, ProductList .

Guys its really cool concept .. !! enjoy it !! :-)

Subhrajyoti Moitra

unread,
Oct 26, 2010, 9:42:20 AM10/26/10
to google-we...@googlegroups.com
IMHO Overlay types are so much better than this round about solution.

WHy cant your servlet just output JSON data instead of some script?

What you are doing manually, would have been done automatically if u used Overlay types.

Anyways, good you were able to sort this problem out.

Thanks,
Subhro.

Jeff Schwartz

unread,
Oct 26, 2010, 10:27:11 AM10/26/10
to google-we...@googlegroups.com
If the servlet is returning json then wouldn't just calling eval(jsonString) in your client create the javascript objects?
Jeff

Thomas Broyer

unread,
Oct 26, 2010, 12:20:11 PM10/26/10
to Google Web Toolkit


On 26 oct, 15:38, Santosh kumar <kopp....@gmail.com> wrote:
> Hi ,
>
> Moitra and Thomas
>
> Thanks for your reply.. !!
>
> Anyways i got a solution..
>
> *use this code in the servlet* ---
> - get the list of products (productList) and use it in the servlet:
> - This is JSON format to form a array of objects
>
>         // Open the <script> tag
>         writer.append("<script type=\"text/javascript\">");
>         writer.append("var product=");
>         writer.append("{productList: '[");
>
>         Iterator<Product> iter = productList.iterator();
>         while (iter.hasNext()) {
>             Product product= iter.next();
>             writer.append("{productName: \"" + Product .getProductName() +
>                     "\", id: " + Product .getId() +
>                     ", productDetails: \"" + Product .getProductDetails() +
>                        .................................
>                        .................................
>                       "\"}");
>             if (iter.hasNext()) {
>                 writer.append(",");
>             }
>         }
>
>         // End the <script> tag
>         writer.append("]'}; </script>");
>
> *use this code in the GWT onModule *---
> - call the above servlet on onModule
>
>         Dictionary product= Dictionary.getDictionary("product");
>         String productListStr = product.get("productList").toString();
>         JSONArray productJSONArray = JSONParser.parse(productListStr
> ).isArray();
>         List<Product> ProductList = new ArrayList<Product>();
>         for (int i = 0; i < productJSONArray .size(); i++) {
>             JSONObject productJSONObject = (JSONObject)productJSONArray
> .get(i);
>             Product product= new Product();
>
>             JSONString productNameJSONString = productJSONObject
> .get("productName").isString();
>             product.setProductName(productNameJSONString .stringValue());
>
>             product.setId(Long.valueOf(productJSONObject
> .get("id").toString()));
>
>             .........................
>             .........................
>
>             ProductList .add(product);
>         }
>
> finally we will get a list of objects. i.e, ProductList .
>
> Guys its really cool concept .. !! enjoy it !! :-)

Rewritten using overlay types:
public final class Product extends JavaScriptObject {
protected Product() { /* required for overlay types */ }

public native String getProductName() /*-{ return
this.productName; }-*/;

public native String getId() /*-{ return this.id; }-*/;
}

...

public native JsArray<Product> getProductList() /*-{ return
$wnd.product.productList; }-*/;

...

JsArray<Product> productList = getProductList();

Of course, if your really want Product as a "real" bean, and a List<?>
instead of a JsArray<?>, you can copy things around (see below); but
really I believe overlay types are much more readable than anything
using com.google.gwt.json.* classes.

// renaming the above overlay type to ProductJSO, and using your
Product bean class:
List<Product> productList = new ArrayList<Product>();
JsArray<ProductJSO> products = getProductList();
for (int i = 0, l = products.getLength(); i < l; i++) {
ProductJSO jso = products.get(i);
Product p = new Product();
p.setProductName(jso.getProductName());
p.setId(jso.getId());
products.add(p);
}

Thomas Broyer

unread,
Oct 26, 2010, 12:21:22 PM10/26/10
to Google Web Toolkit


On 26 oct, 16:27, Jeff Schwartz <jefftschwa...@gmail.com> wrote:
> If the servlet is returning json then wouldn't just calling eval(jsonString)
> in your client create the javascript objects?

The servlet isn't "returning JSON", it's outputting a script to go
right in the "dynamic HTML host page":
http://code.google.com/webtoolkit/articles/dynamic_host_page.html

Sebastian Beigel

unread,
Oct 26, 2010, 12:33:56 PM10/26/10
to google-we...@googlegroups.com
Hi Thomas,

> Of course, if your really want Product as a "real" bean, and a List<?>
> instead of a JsArray<?>, you can copy things around (see below); but
> really I believe overlay types are much more readable than anything
> using com.google.gwt.json.* classes.

I used to use overlay type heavily (returning JSON from a Spring
MVC/Jackson backend) and it worked quite well. Although I found it
quite limiting to be unable to model "real" class hierarchies (JSOs
must not be subclassed). I really do this a lot on the server side. I
also really like to use the enhanced for loop for Lists and just do a
new Foo() instead of some tedious Foo.create(). Last but not least I
don't have a "Generate getters/setters" in Eclipse for my JSOs :)

All this led me to write a Generator which inspects my models ("real"
beans) and emits JSON mapping code handling simple properties, object
graphs and collections. That way I can work with real beans and
collections of beans in my (business) code and do the mapping from/to
JSON in my service/DAO layer (still sending/retrieving JSON to/from my
backend).

Sebastian

Subhrajyoti Moitra

unread,
Oct 26, 2010, 3:25:50 PM10/26/10
to google-we...@googlegroups.com
"All this led me to write a Generator which inspects my models ("real"
beans) and emits JSON mapping code handling simple properties, object
graphs and collections."=>
This is very interesting. Can u give some hints as how to go about writing this Generator?

Thanks,
Subhro.

Harald Pehl

unread,
Oct 26, 2010, 4:18:27 PM10/26/10
to Google Web Toolkit
Feel free to take a look at Piriti (http://code.google.com/p/piriti/).
It's a JSON / XML mapper for GWT using annotations and defered
binding. Using Piriti you can have real POJOs on the client side.
References and inheritance is supported. I'm about to release version
0.6 soon which will add support for JSONPath (http://goessner.net/
articles/JsonPath/) and private fields.

- Harald

On 26 Okt., 21:25, Subhrajyoti Moitra <subhrajyo...@gmail.com> wrote:
> "All this led me to write a Generator which inspects my models ("real"
> beans) and emits JSON mapping code handling simple properties, object
> graphs and collections."=>
> This is very interesting. Can u give some hints as how to go about writing
> this Generator?
>
> Thanks,
> Subhro.
>
> > google-web-tool...@googlegroups.com<google-web-toolkit%2Bunsubs cr...@googlegroups.com>
> > .

Subhrajyoti Moitra

unread,
Oct 26, 2010, 4:33:45 PM10/26/10
to google-we...@googlegroups.com
Thanks Harald for reminding me.
I actually used priti for some xml work. Not JSON.
Yes, i think this also is a good alternative.

Thanks,
Subhro.


To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.

Thomas Broyer

unread,
Oct 26, 2010, 7:02:48 PM10/26/10
to Google Web Toolkit


On 26 oct, 18:33, Sebastian Beigel <sebast...@beigel.de> wrote:
> Hi Thomas,
>
> > Of course, if your really want Product as a "real" bean, and a List<?>
> > instead of a JsArray<?>, you can copy things around (see below); but
> > really I believe overlay types are much more readable than anything
> > using com.google.gwt.json.* classes.
>
> I used to use overlay type heavily (returning JSON from a Spring
> MVC/Jackson backend) and it worked quite well. Although I found it
> quite limiting to be unable to model "real" class hierarchies (JSOs
> must not be subclassed).

You can very well subclass JSOs (see how
com.google.gwt.dom.client.AnchorElement extends Element which in turn
extends Node).
What you cannot do is virtual dispatching (i.e. overring methods:
methods must be final, but not necessarily classes).

> I really do this a lot on the server side. I
> also really like to use the enhanced for loop for Lists

That's why I created JsCollections a while ago with a set of
JsArrays.toArray() methods that copies the JsArray into an array in
DevMode but just "casts" it in prod mode (i.e. no single overhead once
compiled to JS).
http://code.google.com/p/gwt-in-the-air/source/browse/trunk/src/net/ltgt/gwt/jscollections/client/JsArrays.java

> and just do a
> new Foo() instead of some tedious Foo.create().

That's really about "coding style", i.e. personal preference.

> Last but not least I
> don't have a "Generate getters/setters" in Eclipse for my JSOs :)
>
> All this led me to write a Generator which inspects my models ("real"
> beans) and emits JSON mapping code handling simple properties, object
> graphs and collections. That way I can work with real beans and
> collections of beans in my (business) code and do the mapping from/to
> JSON in my service/DAO layer (still sending/retrieving JSON to/from my
> backend).

Note that starting with GWT 2.0 JSOs can implement interfaces (as long
as no more than a single JSO class implements a given interface, so
there's no virtual dispatch) so you can "extract an interface" from
your server-side model and implement it as a JSO on the client side
(that would handily replace the "generate getters/setters" with
minimal effort); and there's work in progress to add a "lightweight
collections" module to GWT: compiles to much lighter weight JS code
than java.util.* collections and are still usable in a JVM (unlike
JsArray).
You'd use Jackson or similar on the server-side to (de)serialize to/
from JSON, and a simple JsonUtils.safeEval on the client side for the
parsing (and new JSONObject(jso).toString() for the serialization,
unless you wrap json2.js for a JSON.stringify emulation on browsers
that don't natively support it)

Sebastian Beigel

unread,
Oct 27, 2010, 4:24:27 AM10/27/10
to google-we...@googlegroups.com
> You can very well subclass JSOs [...] What you cannot do is virtual dispatching (i.e. overring methods:

> methods must be final, but not necessarily classes).

Of course you are right -- I wasn't precise (and thus wrong :) What I
meant (and "hate" :) is that you're not allowed to override methods
and that there is a "one interface to one JSO" constraint (since GWT
2.0). I like to have my domain models implement something like
EntityModel (a custom interface declaring Integer getId() and String
getrLabel() for example). That way, I can really simple build/populate
things like ListBoxes etc. GWT 2.1's ProvidesKey et al. gives us
another (and more flexible) solution for these problems though.

> That's why I created JsCollections a while ago with a set of
> JsArrays.toArray() methods that copies the JsArray into an array in
> DevMode but just "casts" it in prod mode (i.e. no single overhead once
> compiled to JS).

I used to do something similar. For dates and date-times as well (as
these types are Strings in the JSON requests -- this works best for me
at least). But I must admit, I'm lazy and I just (would) prefer to not
think about these conversions and "just use" Lists, Dates etc. as I do
on the server side.

Did you do any comparison in size and performance for the JSO vs.
native beans approach?

Sebastian

Thomas Broyer

unread,
Oct 27, 2010, 6:53:12 AM10/27/10
to Google Web Toolkit


On 27 oct, 10:24, Sebastian Beigel <sebast...@beigel.de> wrote:
> > You can very well subclass JSOs [...] What you cannot do is virtual dispatching (i.e. overring methods:
> > methods must be final, but not necessarily classes).
>
> Of course you are right -- I wasn't precise (and thus wrong :) What I
> meant (and "hate" :) is that you're not allowed to override methods
> and that there is a "one interface to one JSO" constraint (since GWT
> 2.0). I like to have my domain models implement something like
> EntityModel (a custom interface declaring Integer getId() and String
> getrLabel() for example).

Then implement it on a "root" JSO that all your other JSOs will
extend. If you were coding in JavaScript, no doubt you'd give the same
names to the properties in the JS objects (or JSON objects if we think
in terms of "what goes on the wire"), it shouldn't be any different
here, so your getId and getLabel could be final methods (you'd always
do "return this.id" and "return this.label", so why not writing it
once only in a final method?)
You can face an issue if your "label" for instance is not really a
"property" of the object but rather built from other properties
depending on the actual object; but then you should have a getLabel()
method at the JavaScript level, so again you can write your method as
final (return this.getLabel()). This approach wouldn't work if you
objects come from parsed JSON, but then it wouldn't work in "pure JS"
either, so it's not an issue with the tooling and its design, but with
your use of it: JSOs are a bridge between the GWT-Java and the
JavaScript worlds, they're not intended as an "optimization tool".

My rule of thumb is that even though your eyes see Java code, you have
to keep in mind that you're developing in JavaScript in the end.
Either that, or you add an abstraction level, and lose some
optimizations (in this case, you do not use JSOs, and lose their
"lightweightness")

> > That's why I created JsCollections a while ago with a set of
> > JsArrays.toArray() methods that copies the JsArray into an array in
> > DevMode but just "casts" it in prod mode (i.e. no single overhead once
> > compiled to JS).
>
> I used to do something similar. For dates and date-times as well (as
> these types are Strings in the JSON requests -- this works best for me
> at least). But I must admit, I'm lazy and I just (would) prefer to not
> think about these conversions and "just use" Lists, Dates etc. as I do
> on the server side.

See my remark above about abstractions vs. optimizations.

> Did you do any comparison in size and performance for the JSO vs.
> native beans approach?

Not formally no. But JSOs do not generate "class" code (initializing
the prototype, etc.), and in most cases your methods will be inlined
(as they'd do with non-JSOs too, by the way). Lists et al. on the
other hand generate a lot of code re. IndexOutOfBoundsException, etc.
and a enhanced for loop will instantiate an iterator (yet another
class).

Note that I'm not saying you should use/have used JSOs, on the
contrary; I'm just enlightening the fact that JSOs are for a specific
"task", there's no one-size-fits-all: JSOs might fit your needs, but
if they don't, don't fight them, it just means you should use/have
used something else.
When mapping JS libs for use in GWT (such as OpenLayers or the Google
Maps API), JSOs are wonderful! They work quite well when receiving
JSON from your server too, but that's all: accessing "parsed from
JSON" properties from the Java world with a clean syntax, which is
very different from getting "data model beans" (with some "logic" in
them) from JSON! (for that, you'd either wrap a JSO in a GWT-Java
class, or use external "helpers" such as GWT 2.1 ProvidesKey)
Reply all
Reply to author
Forward
0 new messages