Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to genearte JSON on the client

Tags:

json

gwt

In the project, I have to send complex JSON commands form the server to the client. Is it effective to generate JSONObjects ( Strings, Numbers, etc.) convert them to the string and then send them via RequestBuilder or is there a more effective method.

Is it effective to convert JSON objects to string (via the .toString method on the Object)

Code example:

    JSONObject retObject = new JSONObject();
    retObject.put("NumberVar", new JSONNumber(1));
    retObject.put("StringVar", new JSONString("HelloWorld"));

    JSONArray arrayVar= new JSONArray();
    for (int i = 0; i < 5; i++) {
        arrayVar.set(i,
                new JSONString("Array"));
    }
    retObject.put("EventParameters", arrayVar);

    System.out.println(retObject.toString());

Output:

{"NumberVar":1, "StringVar":"HelloWorld", "EventParameters":["Array","Array","Array","Array","Array"]}

Regards, Stefan

like image 583
Stefan Avatar asked Feb 29 '12 13:02

Stefan


2 Answers

The solution you have will work.

If you want to do it more efficiently, and you only want to support modern browsers with support for JSON.stringify(), you can work in JavaScriptObjects instead of JSONObjects and use this native method:

private static native String stringify(JavaScriptObject jso) /*-{
  return JSON.stringify(jso);
}-*/;

Alternatively, you can stringify a JSO by doing:

String json = new JSONObject(jso).toString();

JavaScriptObjects are more efficient because they are represented in the final compiled code as JS objects, while JSONObjects are represented as emulated Java objects. The second solution will mean less overhead while you construct the JSO, but comparatively more (than the first) when you stringify it.

Your solution will work just fine though.

like image 174
Jason Hall Avatar answered Nov 05 '22 19:11

Jason Hall


There's also AutoBeans.

public interface MyJsonFactory extends AutoBeanFactory {
   AutoBean<MyJsonObj> myJsonObj();
}

public interface MyJsonObj {
   @PropertyName("NumberVar")
   int getNumberVar();
   @PropertyName("NumberVar")
   void setNumberVar(int val);

   @PropertyName("StringVar")
   String getStringVar();
   @PropertyName("StringVar")
   void setStringVar(String val);

   @PropertyName("EventParameters")
   List<String> getEventParameters();
   @PropertyName("EventParameters")
   void setEventParameters(List<String> val);
}

MyJsonFactory factory = GWT.create(MyJsonFactory.class);
AutoBean<MyJsonObj> bean = factory.myJsonObj();
MyJsonObj obj = bean.as();
// bean and obj are 2 distinct view on the exact same data
obj.setNumberVar(1);
obj.setStringVar("HelloWorld");
List<String> list = new ArrayList<String>(5);
for (int i = 0; i < 5; i++) {
   list.add("Array");
}
obj.setEventParameters(list);
System.out.println(AutoBeanCodex.encode(bean).getPayload());

The @PropertyName is needed is as your JSON property names do not align with the AutoBean conventions (inspired by Java Beans ones), where getNumberVar() gets a numberVar property (with lower-case n)

like image 39
Thomas Broyer Avatar answered Nov 05 '22 20:11

Thomas Broyer