New Feature: Resource Serving in JSR 286

Posted: August 13, 2007 in Technology

ranjansatya.wordpress.comresource.jpg Recently the JSR 286 draft was available for public review which can be downloaded from this link. It includes some of  the major features which were missed in the JSR 168 spec. You can visit Deepak’s blog to  get a list  of  all those major changes.  One of the major feature introduced  in this  new Portlet  specification is “Resource Serving”  .  In this blog I will  explain  this  feature in detail.

In one line “The resource serving feature provides the ability for a portlet to serve a resource”.

Why it is needed ?

Direct links to the resources in the same portlet web application  are not guaranteed to pass through the portal server and will not have portlet context available. So direct link should be used for the use case where access to the portlet context and access through portal server is not needed.

But the resource url link points back to the portlet. A new interface “ResourceServingPortlet” is introduced in the JSR 286 spec. Via these resource url links serveResource method of ResourceServingPortlet interface is called and portlet can serve the resource which may be protected by the portal security and can leverage portlet context. Portlet container does not render any output in addition to the content returned by the serveResource call. Thus this new life cycle method serveResource() provides more
control to the portlet developer by giving access to write directly on the response object where portal server just acts as a proxy.

The serveResource call can also be used to implement AJAX use cases by invoking resourceURL through XMLHttpRequest in client side javascript. The client side code of the portlet is then responsible for inserting either the markup or otherwise update the page DOM in a non disruptive manner for the other components on the page.

How to Create a Resource URL ?

A resource url can be generated by invoking createResourceURL() method of the RenderResponse object  in render phase of the portlet or doView() method of the Generic Portlet.

The resouce url can also be created inside serveResource() method of the ResourceServingPortlet. In that case portlet developers need to call createResourceURL() method on ResouceResponse object passed to the serveResource() method.

In the following code snippet we will create a resource url inside the doView() and then we will set that url as a IMG source in the rendered output.

public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {

response.setContentType(“text/html”);
PrintWriter writer = response.getWriter();

ResourceURL resURL = response.createResourceURL();
resURL.setResourceID(“image”);
writer.println(“<IMG src=\”” + resURL+ “\” >”);

//Render other markups

}

So when the browser loads the portal page to show the view mode of the portlet, it automatically sends the request for the resURL which goes through portal and finally serveResouce() of  GenericPortlet is called to serve the resource (in this case “image”).

The serveResource() for this example should look like below

public void serveResource(ResourceRequest resRequest, ResourceResponse resResp) throws PortletException, IOException {

resResp.setContentType(“image/png”);
byte[] b = getImage(“MyImage.PNG”);  //Returns image bytes
resResp.getPortletOutputStream().write(b);

}

I have taken the above image example to explain the usefulness of this new feature properly. But  you may also want to create a link for a resource url in your doView() and then on clicking on that link, serverResource() will be called which will only show the output returned from the serveResource().

You can also set a resource id of the resourceURL to enable same serveResource() serving multiple resources. You can also create new resource urls inside serveResource().

The cache level of a resource url can be set through setCacheability() of ResourceURL class though there are certain restrictions in setting cache level. Possible values are: FULL, PORTLET
or PAGE. This helps for Caching of Resouces. To know more about caching in JSR 286 check Karthik’s blog.

You can check out the sources of OpenPortal Portlet Container which has the implementation for serve resource feature of JSR 286. Try it out.

Advertisements
Comments
  1. Trupti says:

    Hi Satya,
    I am trying to use the serveResource method to display an image on the portlet using the method that you have descrived. .But I am getting an error that getOutputStream() has already been called on this response.
    This is the code I have written –
    public class myClass extends GenericPortlet {
    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    ResourceURL resURL = response.createResourceURL();
    resURL.setResourceID("image");
    out.println("<IMG src=\"" + resURL+ "\" >");
    }
    public void serveResource(ResourceRequest resRequest, ResourceResponse resResp) throws PortletException, IOException
    {
    resResp.setContentType("image/png");
    byte[] ImageBytes= getImage();
    resResp.getPortletOutputStream().write(ImageBytes);
    }
    }
    The program does call the serveResource method and I get the error – getOutputStream() has already been called on this response at this line – resResp.getPortletOutputStream().write(ImageBytes)
    I would appreciate any help in trying to figure out what may be the issue here ?
    Thanks,
    Trupti

  2. jmmunozr says:

    As I can see, you are not implementing the ‘ResourceServingPortlet’ interface; then, the portlet container wont invoke the ‘serveResource’ method ever.
    Jose.

  3. satya says:

    The code looks fine to me. I even tried the same code and it’s working for me. Which Portal Server are you using to test your portlet ? I tried with Open Portal Portlet Container and it’s working as expected.

  4. Venkat says:

    Hi Satya,
    The article you posted has good information. Thanks for posting it.
    I have a requirement and thought of sharing with you, hope you will be helpful.
    I have a requirement where i need to read the Portal Page Browser URL
    I am using WebSphere Portal 6.1 and RAD 7.5 using JSR 286.
    So using jsr 286 specifications how can i read the portal browser url.
    To make the requirement more clear, we have an url which comes from
    Legacy (outside the portal environment) and opens the portal page, so
    the url comes into portal environment has an id appended to it.
    as an example the url looks something like this:
    http://www.abc.com/application/100034
    so based on the appended 100034 value my portal page displays the
    content (portlet content).
    Do we have any apis with jsr 286 with which i can read the browser url.
    Regards,
    Venkat.

  5. Hub says:

    Hi Satya,
    Is there a way to have serverResource() called directly without creating a URL that the user has to click?
    In doView() I want to output a PDF directly without having to generate a clickable URL first.
    It looks to me like this is not possible.
    Thanks
    hub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s