Json <-> Java serialization that works with GWT

51,069

Solution 1

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());

Solution 2

Another thing to try is the new AutoBean framework introduced with GWT 2.1.

You define interfaces for your beans and a factory that vends them, and GWT generates implementations for you.

interface MyBean {
  String getFoo();
  void setFoo(String foo);
}

interface MyBiggerBean {
  List<MyBean> getBeans();
  void setBeans(List<MyBean> beans>;
}

interface Beanery extends AutoBeanFactory{
  AutoBean<MyBean> makeBean();
  AutoBean<MyBiggerBean> makeBigBean();
}

Beanery beanFactory = GWT.create(Beanery.class);

void go() {
  MyBean bean = beanFactory.makeBean().as();
  bean.setFoo("Hello, beans");
}

The AutoBeanCodex can be used to serialize them to and from json.

AutoBean<MyBean> autoBean = AutoBeanUtils.getAutoBean(bean);
String asJson = AutoBeanCodex.encode(autoBean).getPayload();

AutoBean<MyBean> autoBeanCloneAB = 
  AutoBeanCodex.decode(beanFactory, MyBean.class, asJson );

MyBean autoBeanClone = autoBeanCloneAB.as(); 
assertTrue(AutoBeanUtils.deepEquals(autoBean, autoBeanClone));

They work on the server side too — use AutoBeanFactoryMagic.create(Beanery.class) instead of GWT.create(Beanery.class).

Solution 3

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.

Solution 4

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.

Solution 5

RestyGWT is a powerful library for encoding or decoding Java Object to JSON in GWT:

import javax.ws.rs.POST;
...
public interface PizzaOrderCodec extends JsonEncoderDecoder<PizzaOrder> {
}

Then:

// GWT will implement the interface for you
PizzaOrderCodec codec = GWT.create(PizzaOrderCodec.class);

// Encoding an object to json
PizzaOrder order = ... 
JSONValue json = codec.encode(order);

// decoding an object to from json
PizzaOrder other = codec.decode(json);

It has also got several easy to use API for consuming Restful web services.

Have a nice time.

Share:
51,069
amartynov
Author by

amartynov

Updated on July 26, 2020

Comments

  • amartynov
    amartynov over 3 years

    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)