I have been doing a fair bit of GWT wrangling lately, but noticed my blog didn’t reflect that.  I thought I’d do a broad survey of GWT server communication strategies.  By server communication, I mean the ability to transfer data to or from or to and from a server.

Since GWT is, at the end, just javascript, these methods that work, work for any javascript code (those that don’t work may fail due to GWT strictures).  But I’ll be looking at them with a particular GWT focus.  I created a sample Eclipse project that shows all of these methods (except for GWT-RPC, since that is so well documented and requires a java server).  I encourage you to download it and toy around with each of these methods.  I used GWT 1.5.3 on Windows, and tested the code in both in the hosted browser and my normal browser (FireFox 3).

For the anxious and impatient, here’s a quick table overview.

Method To server From server Cross domain Payload length Notes
HTTP request yes yes no unlimited (post) developer responsible for making sense of data
GWTRPC yes yes no unlimited (post) only works with java server on the backend
JSON yes yes yes limited by URL length (2048) hard to determine when data is loaded
JSONP yes yes yes limited by URL length (2048)
Form yes yes/no yes unlimited payload no server response available if posting cross domain
Iframe yes yes no limited by URL length cross domain fails

HTTP requests are the simplest way to retrieve data from the server.  The data retrieved can be anything (text, HTML, JSON, XML, some other data format, binary data, etc), but you as a developer are responsible for taking that data and turning it into something your program can use.  Also, since HTTP requests use XMLHttpRequest under the hood, you are limited to the same hostname that your GWT code was served from.  This is the default setting for most browsers (the so called Same Origin Policy)–I did notice that the GWT hosted browser does let you pull HTTP Requests from a different domain, after a warning.  FF3 does not allow the cross domain request at all–it fails without an error message.  Data transmission is two way.  The GWT documentation provides sample code.

GWT-RPC is the method that is given the most attention in the GWT docs.  GWT-RPC provides plumbing to marshal and unmarshal java java objects marked with the Serializable or IsSerializable interfaces.  The data object can’t contain any fields that GWT doesn’t know how to translate, like URI.  GWT-RPC is currently built on XMLHttpRequest and is subject to all of its benefits and limitations.  Data transmission is two way.  The GWT documentation contains sample code.

JSON is a data interchange format that encodes data in a way that can be executed by javascript compilers.  It looks something like this:

var myvar = {"msg":"plain json"};

GWT can use JSON to pull data from remote servers.  Data can be transmitted both ways, but in GWT it is hard to know when the data has been returned from the remote server.  (Also, there are some security implications.  Read the article linked to above.)  You can poll via a Timer to see if a variable has been created. (This is tedious, but may be the best option when the server JSON output is not under your control.)  The closely related JSONP method uses a function instead of a javascript variable, and removes the need for any Timer.

JSONP takes JSON the next step farther and adds a callback function into the mix.  That way, when the remote data has been loaded, a javascript callback function will be executed.  It looks something like this:

my_fcn({"msg":"plain jsonp"});

When the script is loaded, the json is executed, and my_fcn will be executed as well.  I’ve used this quite successfully to make GWT widgets pull data across domains.  This excellent article has an almost complete implementation.  The only thing missing is removing the scrip tag when the callback function is called.  My code just associates a uniqueId with every script element.  After the JSON is parsed, the element is removed.

private native void removeScript(String uniqueId) /*-{
var elem = window[uniqueId+"DOMELEM"];
if (elem != null) {
document.getElementsByTagName("body")[0].removeChild(elem);
}
}-*/;

Form Submission is a method of server communication that really excited me, because I know that in HTMLland, you can do cross domain posts rather easily.  In theory, this means you don’t have to jump through the hoops of JSONP, and can have large amounts of data sent.  Alas, it was not to be.  You can post forms cross domain, but “The result html can be null as a result of submitting a form to a different domain.”  The data does get to the server, though.  If you are trying to get a large amount of data cross domain, this may be useful, but you’ll have to use some kind of polling with JSON or JSONP to determine that the server has handled that data in the way you expected it to.

IFrames were the original remote scripting solution and GWT supports them…kinda.  I was surprised to learn that a cross domain iframe failed in the hosted browser with a security exception.  It also fails in FF3 with the exception: “Permission denied to get property Window.document”.

I hope this tour of GWT server access methods and code is useful to you.

Technorati Tags: , ,

7 thoughts on “GWT Server Communication Strategies

  1. Thomas Broyer says:

    Please, please! JSON != JavaScript!

    First, “JSONP” having “JSON” in its name is an heresy, it’s just JavaScript; your example could have been written:
    (function() { var obj={}; obj.msg = ‘plain jsonp’; my_fcn(obj); })();
    and it would be clear that it’s not JSON (RFC 4627; see http://json.org for an overview)

    What you’re calling “JSON” is just JavaScript too.

    Finally, calling an URL “payload” takes us back in the days where people was saying “How to do a POST with a link? I don’t want to use a GET because it makes URLs ugly” (that was 10 years ago). Hopefully now people know about “REST principles” (“resources” and how URLs identify them) and HTTP caching.

  2. moore says:

    Hi Thomas,

    Thanks for pointing out that I could have used plain old javascript to execute ‘my_fcn’. I used the term JSONP because of the article that introduced me to the concept ( http://code.google.com/support/bin/answer.py?answer=65632&topic=11368 ). You have to admit that JSONP is catchier than “just javascript”.

    I believe what I’m calling JSON ({“msg”:”plain json”}) is JSON, according to the RFC you pointed me to. It’s a fair argument that using JSON in this case is overkill, since it really comes into its own when tranferring complicated data structures.

    Thanks for the comments about the term ‘payload’ being outmoded–while I have heard about REST, I’m afraid I’m not as up to speed on the concept as I should be.

    And thanks for your comments in general.

  3. moore says:

    Note that one of the comments from the ongwt discussion mentioned this new server communication framework: http://code.google.com/p/gwteventservice/

    I have not used this framework, but it certainly looks interesting. If I were writing a complicated GWT application, this LGPL framework would certainly be worth looking at.

Comments are closed.


© Moore Consulting, 2003-2019