2008/10/29

GWT RPC from non-servlet-container (1)

GWT is indeed a beautiful toolkit which does perfect jobs on client side. The most sparking point which I like most is that it is ALL ABOUT JAVA. So it inherits all those beautiful, highly efficient, well-thought-and-examined Java best practices, besides you have so many brilliant tools to use. And BANG!, it compiles cross-platform javascript codes which are run on most of popular browsers nicely. Since it is pure HTTP stuff, it can talks any kind of backend services via web using standard tech such as XML or JSON.

One minor speck is on GWT's proprietary RPC function, in where the backend must be Java and running in a servlet container. There might be some efforts taken on somewhere to let GWT RPC talk with services done other than Java, for example this one. I would like to try something simpler, let GWT RPC being served by non-servlet-container. Although servlet DO rule the market, but still there is alternative, such as Restlet.

The not so much a secret of GWT RPC

Thanks for GWT team's great job, the implementation of service-side GWT RPC is such a breeze which has good structure and not so difficult to get extracted out to be used outside servlet-container.

Actually, the key part of a RPC call is consists of following statements:


RPCRequest rpcRequest = RPC.decodeRequest(payload, this.getClass(), this);
RPC.invokeAndEncodeResponse(this, rpcRequest.getMethod(),
rpcRequest.getParameters(), rpcRequest.getSerializationPolicy());

For RPC.decodeRequest method:
  • The first argument, the payload, is a UTF-8 string directly read from the input stream client request, no weird encode/decode in it;
  • The second argument is the class which implements this RPC's RemoteService interface. So it is the target class in the RPC method is defined;
  • The last argument should be an instance of SerializationPolicyProvider. It provides an instance of SerializationPolicy which instructs how to serialize a Java object from/to a string payload. This is one of the tricky parts which I will explain later.


The RPC.decodeRequest method returns an instance of RPCRequest which takes all necessary data for the RPC call.

The second statement is easier to understand, in which the first argument is the target instance on which this RPC call is to be invoked. The RPC.invokeAndEncodeResponse methods also return a UTF-8 string as result in JSON format (either success or failure). This string can be written back directly to GWT client (the current implementation is to gzip it first).

According to aforementioned, seems we can serve a GWT RPC call from an non-servlet container by:

  1. Prepare an instance of SerializationPolicyProvider
  2. Get to know where to load your class and how to create an instance from it;
  3. Read a UTF-8 string from HTTP request;
  4. Create an instance of RPCRequest and call RPC.invokeAndEncodeResponse as illustrated above.
  5. Write the UTF-8 string back to HTTP response, which content-type must be application/json;charset=utf-8


Where SerializationPolicy come from


SerializationPolicy is something new after 1.4.
RPC now generates a serialization policy file during compilation. The serialization policy file contains a whitelist of allowed types which may be serialized. Its name is a strong hash name followed by .gwt.rpc. This file must be deployed to your web server as a public resource, accessible from a RemoteServiceServlet via ServletContext.getResource(). If it is not deployed properly, RPC will run in 1.3.3 compatibility mode and refuse to serialize types implementing Serializable. (#1297)

Basically, for each RemoteServiceServlet implementation, there is one policy file generated which has a strong hash name. This name is passed by the RPC request payload. We can then use it together with the utility method SerializationPolicyLoader.getSerializationPolicyFileName to load a SerializationPolicy instance. The question is where to find that file under our non-servlet-container environment (says Restlet) and how smart it could be.

The next installment I am going to talk about how to create a GWT application backending with Restlet. Hope it will be fun!

0 comments:

Footer

  © Blogger template 'Grease' by Ourblogtemplates.com 2008

Back to TOP