views:

8412

answers:

11

I am looking for a simple Json (de)serializer for Java that might work with GWT. I have googled a bit and found some solutions that either require annotate every member or define useless interfaces. Quite a boring. Why don't we have something really simple like

class MyBean {
    ...
}

new GoodSerializer().makeString(new MyBean());
new GoodSerializer().makeObject("{ ... }", MyBean.class)
A: 

OK, I deleted my previous answer because it turned out to be exactly what you didn't want.

I don't know how well it works with GWT, but we use the json-lib library to serialize objects in a normal Java project where I work.

It can create a JSONObject directly from a JavaBean, then use the resulting JSONObject's toString() method to get the actual JSON string back.

Likewise, it can also turn JSON back into a JavaBean.

R. Bemrose
Thanks for the answer. I haven't tried this yet, but Java native serializers are most likely based on the reflection, therefore I doubt they can work in GWT environment. I found this project: http://code.google.com/p/gwt-jsonizer/, but it doesn't work properly with the latest GWT :(
amartynov
+1  A: 

I seem to be answering this question a lot...

There's a page on code.google.com titled Using GWT for JSON Mashups. It's (unfortunately) way over my head, as I'm not that familiar with GWT, so it may not be helpful.

R. Bemrose
A: 

Not sure if Jackson (http://jackson.codehaus.org/Tutorial) would work for you. I don't know if there's GWT-specific you are looking for; if not it should work.

But its serialization/deserialization works quite well, like:

// read json, create object

ObjectMapper mapper = new ObjectMapper();

MyBean bean = mapper.readValue(jsonAsString, MyBean.class);

// and write out

StringWriter sw = new StringWriter();

mapper.writeValue(sw, user);

String jsonOut = sw.toString();

You do need accessors (getx() to serializer, setX() to deserialize; can annotate methods with other names), but that's about it.

StaxMan
Jackson is a great tool, but it can't cross compiled by GWT into JavaScript because, perhaps among other things, the object mapper makes heavy use of reflection -- a Java feature not supported in GWT land.
ShabbyDoo
Ah. Yes, makes sense, thanks for pointing that out (given js-to-java conversions)
StaxMan
+3  A: 

It seems that I found the right answer to my question

I figured out that bean to json and json to bean conversion in GWT isn't a trivial task. Known libraries would not work because GWT would require their full source code and this source code must use only Java classes that are amoung emulated by GWT. Also, you cannot use reflection in GWT. Very tough requirements!

I found the only existing solution named gwt-jsonizer. It uses a custom Generator class and requires a satellite interface for each "jsonable" bean. Unfortunately, it does not work without patching on the latest version of GWT and has not been updated for a long time.

So, I personally decided that it is cheaper and faster to make my beans khow how to convert themselves to and from json. Like this:

public class SmartBean {
 private String name;

 public String getName() { return name; }
 public void setName(String value) { name = value;  }

 public JSONObject toJson() {
  JSONObject result = new JSONObject();
  result.put("name", new JSONString(this.name));
  return result;
 }
 public void fromJson(JSONObject value) {
  this.name = value.get("name").isString().stringValue();
 }

}

JSONxxxx are GWT built-in classes that provide low-level json support.

amartynov
Interesting. This seems like bit of a short-coming with GWT to me.But it is good to know there is a way. I may need to do this in future myself, as we have a dashboard app written using GWT.
StaxMan
Yeah, this is why they ended up developing a built-in GWT JSON parser. http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/json/client/ I added a more complete answer, as well.
Eric Nguyen
+9  A: 

Take a look at GWT's Overlay Types. I think this is by far the easiest way to work with JSON in GWT. Here's a modified code example from the linked article:

public class Customer extends JavaScriptObject {
    public final native String getFirstName() /*-{ 
        return this.first_name;
    }-*/;
    public final native void setFirstName(String value) /*-{
        this.first_name = value;
    }-*/;
    public final native String getLastName() /*-{
        return this.last_name;
    }-*/;
    public final native void setLastName(String value) /*-{
        this.last_name = value;
    }-*/;
}

Once you have the overlay type defined, it's easy to create a JavaScript object from JSON and access its properties in Java:

public static final native Customer buildCustomer(String json) /*-{
    return eval('(' + json + ')');
}-*/;

If you want the JSON representation of the object again, you can wrap the overlay type in a JSONObject:

Customer customer = buildCustomer("{'Bart', 'Simpson'}");
customer.setFirstName("Lisa");
// Displays {"first_name":"Lisa","last_name":"Simpson"}
Window.alert(new JSONObject(customer).toString());
Chris Kentfield
Yes, I also realized this recently. Thanks.
amartynov
The main issue I have with overlay types is that they mean you can't use the same object representations on the java side as you do on the GWT side. But I haven't found a better deserialization solution.
mooreds
I believe the best would be to annotate getters and have (de)serialization methods generated at compile time
skrat
Why not just use GWT's built-in JSON libraries? http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/json/client/Or was this not yet available at the time this question was asked? I'll add and answer, below.
Eric Nguyen
@mooreds You can. You can have your GWT JSO implement an interface, but it must be the only type to delare this interface and you must annotate this interface with @SingleJsoImpl. You can then reuse the interface on the server side.
Mark Renouf
mooreds
+2  A: 

In Google Web Toolkit Applications, pages 510 to 522, the author, Ryan Dewsbury, shows how to use GWT code generation to do serialization to and from XML and JSON documents.

You can download the code here; you want the chapter 10 code bundles, and then you want to look in the src/com/gwtapps/serialization package. I did not see a license for this code, but have emailed the author to see what he says. I'll update this if he replies.

Issues with this solution:

  • You have to add a marker interface on all your objects that you want serialized (he uses java.io.Serializable but I imagine you could use others--if you are using hibernate for your backend, your pojos might already be tagged like this).
  • The code only supports string properties; it could be extended.
  • The code is only written for 1.4 and 1.5.

So, this is not an out of the box solution, but a great starting point for someone to build a JSON serializer that fits with GWT. Combine that with a JSON serializer on the server side, like json-lib and you're good to go.

I also found this project (again, some marker interface is required).

mooreds
A: 

Have you tried the google json lib itself? Here is the link- http://sites.google.com/site/gson/Home

I dont know if it has a direct support from client GWT or not.

mandar
Close, but even better is GWT's built-in JSON parser. http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/json/client/ I added a more complete answer, as well.
Eric Nguyen
+3  A: 

Check this:

GWT Professional JSON Serializer: http://code.google.com/p/gwtprojsonserializer/

!Works with GWT 2.0+!

Krunoslav Funtak
At this point, the state-of-the art is GWT's built-in JSON parser. http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/json/client/ I added a more complete answer, as well.
Eric Nguyen
The question was about serialization, not parsing...
Mark Renouf
A: 

It is important to say that standard java JSON libraries can not be used for this purpose. It must be compiled for GWT client side into javascript.

This is fully functional GWT client side JSON serializer:

GWT Professional JSON Serializer: http://code.google.com/p/gwtprojsonserializer/

!Works with GWT 2.0+!

Krunoslav Funtak
I think the best solution is to use GWT's built-in JSON parser. http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/json/client/ I added a more complete answer, as well.
Eric Nguyen
+3  A: 

The simplest way would be to use GWT's built-in JSON API. Here's the documentation. And here is a great tutorial on how to use it.

It's as simple as this:

String json = //json string
JSONValue value = JSONParser.parse(json);

The JSONValue API is pretty cool. It lets you chain validations as you extract values from the JSON object so that exceptions will be thrown if anything's amiss with the format.

Eric Nguyen
Thanks. Imho, overlay types are more elegant though.
amartynov
Not to mention, far more efficient.
Mark Renouf
+1  A: 

Try this serializer from Google Code: http://code.google.com/p/json-io/

If you need to write or read JSON format in Java, this is the tool to use. No need to create extra classes, etc. Convert a Java object graph to JSON format in one call. Do the opposite - create a JSON String or Stream to Java objects. This is the fastest library I have seen yet to do this. It is faster than ObjectOutputStream and ObjectInputStream in most cases, which use binary format.

Very handy utility.

John