Update on JSR-286 and Ajax

Early this year I have blogged about the problems related to portlets using Ajax to update their UI from the client side, and my attempts at addressing those. See here and here. As I mentioned in those posts, I also tried to make the model a part of the JSR-286 API. Here is an update of where things stand now.

As far as trying to introduce an end-to-end model into JSR-286, as you will find it in the latest draft specification, the expert group was unable to a come to a conclusion, for a number of reasons. As a result, the specification does not provide an end-to-end programming model for portlets using Ajax. This is disappointing.

To be specific, the goals of an end to end Ajax programming model for portlets were the following:

  • Allow state-changing requests (e.g. via an action URL) initiated via a client API
  • Support state changes via processAction
  • Provide first-class support for the new coordination models (i.e. events and shared/public render parameters) being introduced into JSR-286.
  • Provide a client API that is easy to migrate to, and can easily be plugged into various JavaScript frameworks.
  • Design the client API such that portals can consistently manage the UI and its state in the browser.

These goals were important for a portlet API, as these allow portlets to drive requests from the client side via Ajax, and without sacrificing most of the features available to portlets on the server side programming model.

The expert group almost had a solution – a client side API called XMLPortletRequest, and a server side model via a new lifecycle method called processFragment. The expert group discussed these for a long time, and finally voted against the solution for a number of reasons. Some felt that the expert group is not qualified to design a solution. Some felt that they did not have the time to implement and test it before the specification was finalized, while others felt that the life cycle method getResource newly being introduced into JSR-286 is sufficient for at least a good number of use cases. Note that this is my understanding, and other members of the expert group may have other views – so please don’t consider this post as the expert group’s voice.

Where does it leave the specification? As far as the standard API is considered, there will be a partial solution in the form of a new lifecycle method called serveResource.

public void serveResource(ResourceRequest request, ResourceResponse response) {
// Generate some response

The semantics of this idempotent method are as follows:

  • Portlet can receive form parameters, uploads etc from the request, just like the way a servlet can do.
  • Portlet can write any kind of response. The response content type is open ended, just like the way a servlet can render any kind of content during its service() method.

JSR-286 also introduces a new URL type ResourceURL that can be used to invoke the serveResource method of a portlet.

How is this lifecycle method relevant for Ajax? Since serveResource mimics the service method of the servlet API, portlets can use XMLHttpRequest with a ResourceURL, generate some textual or XML response, and process it in the browser. Here is an example:

var request = new XMLHttpRequest();
request.onreadystatechange = function() {
// Process the response
};'GET', <portlet:resourceURL/>, true);

This is simple, and easy to implement.

But this lifecycle does not come without limitations. Since this is an idempotent operation, portlets can’t make changes to state maintained by the container (such as render parameters), or use features coordination mechanisms introduced in JSR-286.

In particular, JSR-286 introduces two forms of coordination mechanisms, viz., events, and public render parameters. Both these follow a publish-subscribe model. Portlets can fire events, and others can subscribe and receive those events. Similarly, portlets can make some of their render parameters as public, and the container/portal will relay changes to those public parameters to other portlets that have marked the same parameters as public. The key goal of these features is to introduce some kind of dynamism into the UI, by letting portlets exchange events/data without being coupled to each other. However, portlets using serveResource can not take advantage of these facilities.

In my view, JSR-286 misses the bus yet again, unfortunately, forcing implementors to come up with proprietary solutions.

Write a Comment