Portlets and Ajax - How Complete are the Standards?
Every other web developer that I talk to is trying to figure out how best to use Ajax in their apps either to provide some slickness to web apps, or to avoid total page refreshes. In most cases, writing the server side processing code is trivial. You can use JSPs, servlets, struts, JSF or whatever to process Ajax request, and return data (as XML) or markup (as HTML) fragments. Writing client side scripts is where all the fun is. But when it comes to portlets, server side processing for Ajax requests gets tricky. Portlet related standards like JSR168 and WSRP 1.0 do have some limitations in supporting server-side processing of Ajax requests. These specs leave out a few details that limit the use of portlets to process Ajax requests and return data or markup. Read on, if you are interested in finding out what works, what does not and why.
Why Portlets for Ajax?
First of all, why use portlets to do server-side processing of Ajax requests. Here is why?
- Portlets are ideally suited for rendering fragments of markup. Portlets have the right programming model
that lets portals aggregate those markup snippets into full pages. The only difference
with Ajax is that, instead of letting a portal aggregate portlets into a full page, you let the browser do
the aggregation on demand using JavaScript. - Most useful portlets are full-fledged applications that encapsulate all the UI, page navigation, and some controller logic to drive the UI. If you want to use Ajax in the portlet’s UI, it is best to process their Ajax requests within the same portlet. This makes development, deployment, and administration easy.
- Portlet containers provide a runtime for portlets. The runtime provides facilities for URL (re)writing, state management, portlet preferences etc. You may want take advantage of these while processing Ajax requests.
- Finally, portlets make plug-and-play of UI possible, and both JSR168 and WSRP 1.0 do a decent job of supporting such plug-and-play.
There is one key difference between developing portlets, and page-oriented web apps. With portlets, the requests are usually proxied through a portal (or another aggregating application, usually called as a consumer) to portlets. In this case of remote portlets that rely on WSRP1.0, the proxying goes one step further, and the requests are routed via a web services layer from the portal to portlets hosted remotely. Depending on how portlets are deployed, in most cases, browsers may not be able to send a HTTP request to portlets directly. Security restrictions may prevent such access. So, creating URLs correctly is important, and JSR168 and WSRP 1.0 provide ways to create URLs.
Types of URLs
JSR168 and WSRP 1.0 provide for three kinds of URLs that portlets can create in their markup. These are (a) action URLs, (b) render URLs, and (c) resource URLs.
- Action URLs: Action URLs are meant for processing data submitted by the client, make necessary state changes to the portlet, and then render the output. Since action URLs can cause state changes, and are analougus to HTTP POST. In JSR168,
javax.portlet.RenderResponse.createActionURL()can be used to create action URLs. - Render URLs: Render URLs are meant for letting the user navigate to another view of a portlet without causing
any state changes. Render URLs are are anologuous to HTTP GET. In JSR168,javax.portlet.RenderResponse.createRenderURL()can be used to create action URLs. - Resource URLs: Unlike render and action URLs, resource URLs are meant to serve resources. Anything that the browser can directly download is a resource. Examples include images, files etc. To create a resource URL, you can create a URL to the resource, and then let
javax.portlet.PortletResponse.encodeURL()encode it.
I have come across some bloggers that attempted to use some of these URLs, and had partial success. When these specs were designed, Ajax related use cases were not specifically considered. So, the question is, will these URL types help portlets process Ajax requests?
Are these URLs any Good?
Here is the answer. JSR168 and WSRP 1.0 do not allow portlets to process Ajax requests. This was not by design but largely by omission in the specifications. Note that I’m not saying that you can not use Ajax with Portelts’ markup. I’m only saying that you cannot get portlets to respond to Ajax requests.
In both JSR168 and WSRP 1.0, if you want a portlet to process a request, the URL used to submit the request must either be a render URL or an action URL. When submitted, both these types of URLs cause the portal (or the consumer) to delegate the request to the portlet container (or the producer), which will then cause the portlet to process the request. So far so good.
But the trouble is with how portals treat the response from the portlet. Let’s say, in response to a render request submitted via XMLHttpRequest, a portlet made some database calls, queried some data, and generated some XML representing that data. But the contract of render URLs is such that, portals try to aggregate the portlet’s response along with response from other portlets present in the same page. The net result is that, instead of getting the XML data as is, the browser would end up getting a full HTML page. This will most likely break the JavaScript which is expecting just the XML data in the response. The same is the case with action URLs.
What is Possible?
This leaves portlets to work with resource URLs for processing Ajax requests. Unlike action and render URLs, resource URLs can not be handled by portlets directly. This means that you need to keep the code to process Ajax requests outside portlets, and use resource URLs to submit Ajax requests. This works with Ajax since portals don’t try to aggregate other portlets in the same response.
To restate, the key limitation with JSR168 and WSRP 1.0 is lack of sematics to allow portlet’s response to be returned directly to browsers without page aggregation. This may change in JSR286 and WSRP 2.0. I’m less optimistic about WSRP 2.0 given that the specification has just been voted as a committee draft. But JSR286 is still in early stages.
Where does this leave portlet developers trying to use Ajax in their portlets? Use resource URLs, or some vendor specific extensions or APIs to deal with Ajax.
One final note. The current draft of WSRP 2.0 has some improvements for resource URL processing over WSRP 1.0. With WSRP 2.0, portlets can also process resource URL requests. JSR286 will most likely have a corresponding API change. These changes would allow portlets to process Ajax requests via resource URLs. Neither spec is final yet.



Action URLs are idempotent ?
Fix the section on RenderURLs.
You have
“Render URLs are are anologuous to HTTP GET. In JSR168, javax.portlet.RenderResponse.createActionURL() can be used to create action URLs.”
Make it “createRenderURL() can be used to create render URLs”
Thanks Mr Bond :)