Portlets

In order to understand what a portlet is, it is very necessary to understand what a portal is. According to the Portlet Specification, "a portal is a web application that commonly provides personalization, single sign on, content aggregation from different sources, and hosts the presentation layer of information systems. Aggregation is the act of integrating content from different sources within a web page."


Portal functionality can be divided into three main parts:
  1. Portlet container: A portlet container is very similar to a servlet container, in that every portlet is deployed inside a portlet container that controls the life cycle of the portlet and provides it with necessary resources and information about its environment. A portlet container is responsible for initializing and destroying portlets and also for passing user requests to it and collecting responses.
  2. Content aggregator: As defined in the Portlet Specification, one of the main jobs of a portal is to aggregate content generated by various portlet applications. We will talk more about this in the "How a Portal Page is Created" section.
  3. Common services: One of the main strengths of a portal server is the set of common services that it provides. Services are not part of the portlet specification, but commercial portal implementations provide a rich set of common services to distinguish themselves from their competitors. A few common services that you can hope to find in most implementations are:
    • Single sign on: Allows you to get access to all other applications once you log into the portal server, meaning you don't have to log into every application separately. For example, once I log in to my intranet site, I should get access to my mail application, IM messaging application, and other intranet applications, without having to log into each of these applications separately.
A portal server will provide you with a secured credentials store. What you do is to go to the mail application and specify your user name and password once. This information will be stored in the credentials store in encrypted form. From the next time onwards, when you log into your intranet site, the portal server will read your credentials from the store and log into your mail server on your behalf. The same goes for other applications.
    • Personalization: The basic implementation of personalization service allows a user to customize her page in two ways. First, the user can decide what colors she wants for title bars and what icons she wants for controls. Second, the user can decide which portlets she wants on her page. For example, if I'm a big sports fan, I will probably replace the stock and news update portlets with a portlet that lets me track my favorite team.
There are also a few advanced commercial implementations of personalization services that allow you to decide which applications should be displayed to user based on criteria such as his income or interests. In this case, you can create some business rules like "Show the premium products portlet to any user with X amount of income" and "Show the discount deals portlet to users with Y amount of income."
  1. There are a few more common services such as machine translation, in which case the portal server will take content generated by portlet in one language and machine translate it into a language requested by user. Most of the commercial portal servers provide access via handheld devices and are capable of generating different content for different browsers.
Similar to servlets, portlets are web components that are deployed inside of a container and generate dynamic content. On the technical side, a portlet is a class that implements the javax.portlet.Portlet interface and is packaged and deployed as a .war file inside of a portlet container.
Portlets are similar to servlets, in that:
  1. Portlets are managed by a specialized container.
  2. Portlets generate dynamic content.
  3. A portlet's life cycle is managed by the container.
  4. Portlets interact with web client via a request/response paradigm.
Portlets are different from servlets, in that:
  1. Portlets only generate markup fragments, not complete documents.
  2. Portlets are not directly URL addressable. You cant send somebody URL of a portlet. You can send him the URL of the page containing a portlet.
  3. Portlets cannot generate arbitrary content, since the content generated by a portlet is going to be part of portal page. If a portal server is asking for html/text, then all portlets should generate text/html content. On the other hand, if the portal server is asking for WML, then each portlet should generate WML content.

Portlets do provide some additional functionality.
  1. Persistent storage for preferences: Portlets provide a PortletPreferences object for storing user preferences. These preferences are stored in a persistent data store, so they will be available across server restarts. As a developer, you don't have to worry about the actual implementation of how it is stored.
  2. Request processing: Portlets provide much more refined request handling. A portlet may get a request when user takes some action on it (a state called action phase), or because the user took action on some other portlet and the page needs to be refreshed. A portal server provides different callback methods for handling both situations.
  3. Portlet modes: Portlets use a concept of mode to indicate what user is doing. When using a mail application, you may be using it for reading, composing, or checking mail messages--this is the expected functionality of a mail application. Portlets normally provide this in VIEW mode. But there are other activities, like specifying a refresh time or (re-)setting the username and password. These activities allow the user to configure the behavior of the application, so they come under EDIT mode. Help functionality of the mail application comes under HELP mode.
  4. If you think about it, you will find none of these represents new functionality. Instead, most of these are common business requirements. The only thing the portlet specification is doing is providing you one layer of abstraction, so that it will be useful for all stake holders end users, developers and administrators.
  5. As a developer, I put all my business logic related to VIEW mode in a method called doView(), and I put business logic related to the configuration of my application in a doEdit() method, with help-related logic in a doHelp() method.
  6. This makes it simple for an administrator to control access in the portlet application, because all he has to do is change access rights of the portlet to dictate what things a user is allowed to do. For example, a user of a mail application is supposed to specify his username and password in EDIT mode, so it makes sense for him to have access to EDIT mode.
  7. But consider the case where I am the administrator of an intranet site and my company bought a third-party portlet application that displays news updates. This application allows a user to specify the URL from where it can retrieve updates. I want to use this application for displaying internal company news to users. Another requirement is that I don't want users to use this application for tracking any other news source. So as the administrator, I can specify the URL of an internal news update site for all users, and take out their edit privileges by changing the deployment descriptor of this portlet application.
  8. Using portlets makes my website much more appealing to the end user because she will get a similar UI for all her portlet applications. If she wants to read help information about any of the applications, she can click the help button. She will also know that clicking on an edit button will take her to a configure screen for that application. Standardizing the user interface will make your portlet application more appealing.
  9. Window state: The window state determines how much space should be given to content generated by a portlet on a portal page. If you click on the maximize button, the portlet will take up the entire screen and it will become the only portlet that will be available to the user. In minimized state, the portlet will be displayed as only a title bar. As a developer, you should customize your content based on the space available to you.
  10. User information: Commonly, portlets provide content personalized to the user making the request. To do this effectively, they may require access to user attributes such as name, email, phone, etc. The Portlet API provides the concept of user attributes for this. A developer can access these attributes in a standard way, and it is the responsibility of the administrator to map these attributes to an actual user information repository (usually an LDAP server).
Portlets vs. Servlets: Request Processing with Web Components

Like servlets, portlets are Web components and their lifecycle is managed by the portlet container. The portlet container is responsible for loading, instantiating, initializing, and routing requests to the portlet instance and destroying the portlet instance. If you have worked with servlets, you can easily correlate the responsibilities of a portlet container to that of a Web container. So what differentiates a portlet from a servlet component when both are Web components? Let's take a quick look at some of the main shortcomings of servlets:
  • Content aggregation
    Servlets are not appropriate for content aggregation. If you want to use a servlet to aggregate content on a Web page, the responsibility of aggregating and presenting the content in distinct windows is with the servlet itself. In case of portlets, the portal server is responsible for aggregating the content generated by different portlets and showing disparate content in distinct portlet windows on the portal page.
  • Personalization
    If you want to personalize the content in your servlets-based application, you have to create appropriate data structures for saving the user's personalization data, write the code to retrieve and save the personalization data, and so on. In case of portlets, the portlet container is responsible for saving/retrieving the preferences data and it saves the portlet developer from the pain of keeping up with how and where the personalization options are saved.
  • Event-based communication
    If you need to have interservlet communication, the only option is to use Servlet API to directly invoke a servlet. Portlets, on the other hand, provide interportlet communication using events. Use of events keeps the communicating portlets loosely coupled and you can easily add or remove the portlets that receive the events.
Now that we know high-level differences between portlets and servlets, we are ready to look at how request processing in portlets is different from that in servlets.

Multiple request-processing phases

The advantage of portlets over servlets is attributed to its unique request-processing lifecycle. In case of servlets, a request results in the invocation of a servlet's service method, which performs a certain action and generates a complete Web page. Request processing in portlets is a more involved process because each portlet request goes through multiple request-processing phases in its lifecycle. The request-processing phases in a portlet are render, event, resource, and action phases, with each request-processing phase performing a well-defined role in the overall processing of a portlet request. Table 1 describes the purpose of each of these phases in the portlet request-processing lifecycle.
Table 1. Request-processing phases in a portlet
Request-processing phase
Purpose
Render
In the render phase, a portlet generates content, that is, HTML or WML markup.
Action
In the action phase, a portlet performs state-changing functionality like database update.
Resource
In the resource phase, a portlet serves resources, like PDF files.
Event
In the event phase, a portlet responds to the events received by the portlet.

if you compare the request-processing phases of portlets with that of servlets, you'll find similarities between action and render phases of portlet with that of servlet request processing. Like portlets, servlets also perform action and generate markup, the only difference being that a servlet does it in a single phase and portlets have more well-defined phases for markup generation and action processing. It is important to note that not all request processing phases apply to a request received by the portlet. For instance, if the request is received for processing an action (also referred as an action request), only action and render phases apply to the request. If the request is received for generating content (also referred to as render request), only the render phase applies to the request. This means that portlets not only have the concept of multiple request-processing phases but also have the concept of multiple request types.

Each request-processing phase of a portlet maps to a method in the portlet class, which is responsible for the processing request in that phase. For example, the render phase maps to the render method of a portlet class and the action phase maps to the processAction method. You can safely assume that each request-processing phase is represented by a method in the portlet and the action request phase is always the followed by render request phase.

Let's now look at how the concept of multiple request-processing phases in portlets makes them an ideal candidate for developing Web portals that aggregate content from different sources. Figure 1 shows the workings of a Web portal, which has portlets A and B on one of its portal pages.
                                                         
Request-processing phases of a portlet apply to the incoming request based on the request type (action or render). The portlet's render method is always called to ensure that the updated portlet content is displayed by the Web portal.

Methods to Override
When extending from the GenericPortlet abstract class, the following methods should be overridden:
public void init(PortletConfig config)
The container calls this method once when the portlet object is created.

protected void doView(RenderRequest req, RenderResponse resp)
The render method calls this method when the portlet is in VIEW mode. The GenericPortlet class’ default implementation only throws an exception.

protected void doEdit(RenderRequest req, RenderResponse resp)
The render method calls this method when the portlet is in EDIT mode. The GenericPortlet class’ default implementation only throws an exception.

protected void doHelp(RenderRequest req, RenderResponse resp)
The render method calls this method when the portlet is in HELP mode. The GenericPortlet class’ default implementation only throws an exception.

public void processAction(ActionRequest req, ActionResponse resp)
The GenericPortlet class includes a default implementation that only throws an exception.

public void destroy()
The container calls this method on the portlet when the portlet is being taken out of service.
Render Request Processing.

The request from the client is encapsulated in a RenderRequest object. The portlet uses this object to access information about the request that was received from the client by the Portal Server. Typically, the current portlet mode and request parameters included in the incoming request is the information that is accessed. The portlet’s response is encapsulated in a RenderResponse object. Portlet use this object to set the content type of the response and send their portlet content to the portlet container.

Each request object is valid only within the scope of a particular processAction() or render() method call.
Action Request Processing.

Action URL requests from the client are encapsulated in an ActionRequest object. The portlet uses ActionRequest objects to gain access to the details of the incoming HTTP request from the client. The portlet’s response to the action request is encapsulated in the ActionResponse object. The portlet uses this object to set the new portlet mode (typically the VIEW mode) and send information to the subsequent render request after action request has been proceessed.


Portlet Preferences

  1. The portlet specification mandates that portlet container provide persistent store for portlet preferences. Portlets can only access their preferences during requests (render or action). Portlet preferences are encapsulated by the PortletPreferences interface.
  2. Portlets can update their preferences within the processing of the processAction() method. An exception is thrown if the portlet attempts to update preferences during a render request.
  3. User preferences are stored and accessed through a PortletPreferences object. A handle to this object can be obtained by using both RenderRequest.getPreferences() and ActionRequest.getPreferences(), depending from which method the attempt to access the preferences is made. An individual preferences is called using getValue() or getValues(), for single string value or multiple string values respectively. The methods setValue() and setValues() modifies the preference, but no changes are stored in the datastore until the method store() is called. All user preferences must be defined in the portlet deployment descriptor.
  4. Preferences defined at the organization will affect the user’s preference only if the user’s preference has not been defined and only until the user modifies the individual preference. Once preferences have been modified, it will retain its value, even if blank, until the reset() method is called on the preference.
  5. LDAP attributes can only be accessed through the portlet implementation of a user info Map. All attributes needed within the portlet must be defined in the portlet deployment descriptor. The attribute map of all such defined attributes can be retrieved using either ActionRequest.getAttribute(PortletRequest.USER_INFO) or RenderRequest.getAttribute(PortletRequest.USER_INFO). Each attribute can then be retrieved using Map.get("Attribute Name").
  6. Only user attributes defined in the deployment descriptor can be read. The user info map returned is unmodifiable.

JSR 168

The Java Portlet Specification V1.0 was developed under the Java Community Process as Java Specification 


Request JSR 168.
The Java Portlet Specification V1.0 introduces the basic portlet programming model with:
  • two phases of action processing and rendering in order to support the Model-View-Controller pattern.
  • portlet modes, enabling the portal to advise the portlet what task it should perform and what content it should generate.
  • window states, indicating the amount of portal page space that will be assigned to the content generated by the portlet.
  • portlet data model, allowing the portlet to store view information in the render parameters, session related information in the portlet session and per user persistent data in the portlet preferences.
  • a packaging format in order to group different portlets and other Java EE artifacts needed by these portlets into one portlet application which can be deployed on the portal server.
  • Portal development is a way to integrate the different web-based applications for supporting deliveries of information and services.
JSR 286

JSR-286 is the Java Portlet specification v2.0 as developed under the JCP and created in alignment with the updated version 2.0 of WSRP.[1] It was developed to improve on the short-comings on version 1.0 of the specification, JSR-168. Some of its major features include:[2]
  • Inter-Portlet Communication through events and public render parameters
  • Serving dynamically generated resources directly through portlets
  • Serving AJAX or JSON data directly through portlets
  • Introduction of portlet filters and listeners
Portlet Request Processing
Now it's time to talk about a most interesting aspect of portlet technology: how portlets process a request. We will take one backward step first. In the previous article's How a Portal Page is Created section, we said that most portals are implemented as web applications, and are deployed in an application server. In the case of Pluto, the org.apache.pluto.portalImpl.Servlet is mapped to receive all requests. So the first point of contact is a servlet that gets the browser request and generates markup.

Play little with your HelloWorld application a little bit, and you will note that whenever you are interacting with one of the portlets, the whole page gets refreshed. In other words, if you perform some action on Deploy War Admin Portlet, the complete page will get refreshed instead of only that portlet.
Let's look at an example of what happens when you're interacting with a portal. We will assume that you have two portlets, called A and B, on one page. Portlet A can get a request in either of two cases.
1.      The user clicked a link or submitted a form in Portlet A. In this case, Portlet A should do something, like execute some business logic and generate new markup. This is called action processing because the user is performing some action on Portlet A.
2.      The user is performing some action on Portlet B, and as a result, the complete page needs to be regenerated. Please note that when the user performs this action, the browser won't only update the content of Portlet B; instead, it will ask the portal server to regenerate the complete page. In this case, Portlet A should not execute any business logic; instead, it should regenerate markup. This is called the render phase.
Figure 2 shows how a request is handled in the portal server.





Figure 2. Portal request handling
When the user clicks a link on Portlet A, the browser will submit the request to the portlet container. The portlet container will be notified that some action was performed on Portlet A, and will call the processAction() method of Portlet A. This is called the action processing phase. Once action processing is complete, the container will start the render phase. In this phase, the container figures out how many portlets are on the requested page. In this case, there are two portlets, A and B, so it will call the render() method of both these portlets in different threads. Once control returns back from both these methods, it will take the content/fragment generated by them and aggregate it to build the complete page. So when the user performs action on one of the portlets, the page gets the processAction method call and all portlets on the page get a render method call.


What happens if user clicks the Refresh button? Or what if the user visits or returns to the page where both of these portlets are placed? The container has to generate markup for the page, but no action is performed on any of the portlets. In this case, when the container gets the request, it will skip the action phase and in the render phase it will call the render() method of all portlets on the page.
The portlet interface has two different methods to represent two different phases of request processing.
1.      processAction(ActionRequest actionRequest, ActionResponse actionResponse): The portlet container will call this method when some action is performed on a portlet. It will pass information submitted by the user, such as values entered in a form, in an ActionRequest object. You can use the ActionResponse to redirect the user to a new page.
2.      render(RenderRequest renderRequest, RenderResponse renderResponse): This method is similar to the service() method in the Servlet API. It is called in the render phase, but you should not override it directly. Instead, you override one of the mode-specific methods, such as doView(), doHelp(), or doEdit(). The render() method will determine the mode requested by the user and call the appropriate doMode() method. The portlet container will pass a RenderRequest and RenderResponse to this method. The developer can write markup via the object returned by renderResponse.getWriter(). But RenderRequest does not directly get HTML form values submitted by the user--instead, it has go through PortletSession. This is getting complicated, so we will handle it separately in the next section.

Greet User with Personalized Message


In last section we talked about how the portlet container processes requests. In this section, we will clarify portlet request processing concepts by changing the HelloWorld portlet to handle the processAction() method call. What we will do is ask user for his or her name in EDIT mode, and then use that name to greet the user in VIEW mode. Follow these steps:
1. Change the HelloWorld.java file, like this.
2.  protected void doView(RenderRequest renderRequest,
3.  RenderResponse renderResponse)
4.  throws PortletException, IOException {
5.  renderResponse.setContentType("text/html");
6. String userName = (String) renderRequest.
7.  getPortletSession().getAttribute("username");
8.  if (userName != null)
9.   renderResponse.getWriter().println("Hello " 
10. + userName);
11.  else
12.    renderResponse.getWriter().println("Hello how
13.     are you doing. Go to edit mode and set name");
14.}
15. 
16.protected void doEdit(RenderRequest renderRequest,
17.RenderResponse renderResponse)
18.throws PortletException, IOException {
19.  PortletRequestDispatcher dispatcher =
20.  getPortletContext().getRequestDispatcher(
21.    "/html/username.jsp");
22.  dispatcher.include(renderRequest, renderResponse);
23.}
24. 
25.public void processAction(ActionRequest
26.actionRequest, ActionResponse actionResponse)
27.throws PortletException, IOException {
28.  String userName =
29.    actionRequest.getParameter ("username");
30.  actionRequest.getPortletSession().setAttribute
31.    ("username", userName);
32.  actionResponse.setPortletMode(PortletMode.VIEW);
33.}
As you can see, we have to make lots of changes in HelloWorld.java in order to greet the user with his or her name. Let's take a look at each of these changes.
    1. doEdit(): Now we pass control to username.jsp to generate a form that will ask the user for his or her name.
    2. processAction(): This method gets called only when user goes to EDIT mode and submits a form. Inside of this method, the first thing we do is to call actionRequest.getParameter() to find the value of the userName input submitted by the user.
We then set this value as an attribute in the portletSession object. Please note that the ActionRequest object is different than RenderRequest, so you can set an attribute in ActionRequest and expect it to be available in RenderRequest. Also the portlet container will create only one instance of Portlet to serve multiple requests (similar to Servlet), so you cannot pass a value from the action phase to the render phase as an instance or static variable of the Portlet class. The last line is actionResponse.setPortletMode(PortletMode.VIEW). This is called because once the user submits a name, we want to change the mode back to VIEW mode. This way, when the render() method is called, it will route the user request to the doView() method instead of the doEdit() method.
    1. doView(): In this method, we will check if the userName attribute is already set in the PortletSession object. If so, we use the value of that attribute to greet the user; if it is not set, then we display a message informing the user how to set userName.
  1. Create /html/username.jsp inside of the Web Content folder. This JSP will be used to solicit input from the user in EDIT mode.
35.<%@ page language="java"%>
36.<%@ taglib uri="http://java.sun.com/portlet"
37.prefix="portlet"%>
38.<portlet:defineObjects/>
39.<form action='<portlet:actionURL />'>
40.<table>
41.<tr>
42.        <td>User Name</td>
43.        <td>
44.                <input type="text" name="username"/>
45.        </td>
46.</tr>
47.<tr>
48.        <td>
49.                <input type="submit" label="Save"/>
50.        </td>
51.</tr>
52.</table>
</form>
This JSP is like any typical JSP with the difference of the <portlet:defineObjects> tag. The portlet specification defines the portlet tag library with the aim of solving common problems faced by portlet developers. The portlet tag library is very important concept, and we'll revisit it shortly.
Build your application and deploy it on Pluto. When you go to VIEW mode, it will ask you to go to EDIT mode and enter a user name. Enter userName and click Submit; this should take you back to VIEW mode, which will display a message saying "Hello your-name." You know, one of the problems of being a UI developer is that you don't feel like you're learning something unless you see some change in the UI.




The Portlet Tag Library

The portlet specification mandates that every portlet container should provide an implementation of the portlet tag library, portlet.tld. The portlet tag library enables JSPs that are included by portlets to have direct access to portlet-specific elements such as RenderRequest and RenderResponse. It also provides JSPs with access to portlet functionality such as the creation of portlet URLs. JSP pages using the tag library must declare this in a taglib declarative statement like this (using the suggested prefix value):
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
Available tags include the following:
1.      <portlet:defineObjects/>: This tag must appear to define the following variables in the JSP page: renderRequest, renderResponse, and portletConfig. A JSP using the defineObjects tag may use these variables from scriptlets throughout the page.
2.      <portlet:actionURL/>: The portlet actionURL tag creates a URL that must point to the current portlet and must trigger an action request with the supplied parameter. The parameters may be added to the URL by including the param tag between the actionURL start and end tags:
3.  <portlet:actionURL windowState="maximized" portletMode="edit">
4.          <portlet:param name="action" value="editStocks">
</portlet:actionURL>
The example creates a URL that brings the portlet into EDIT mode and MAXIMIZED windowState to edit the stock quote list.
5.      <portlet:renderURL/>: This tag creates a URL that must point to the current portlet and must trigger a render request with the supplied parameter. The renderURL tag also takes parameters using the param tag, and allows the attributes forwindowState and portletMode.
6.      <portlet:namespace/>: This tag produces a unique value for the current portlet. Namespacing ensures that the given name is uniquely associated with this portlet and avoids name conflicts with other elements on the portal page or with other portlets on the page.
<A HREF="javascript:<portlet:namespace/>test()">Encoded name</a>


Portlet Preferences

One of the requirement for portlets is that the user should be able to customize their view or the behavior of the portlet. The portlet specification provides you with a PortletPreferences object that allows you to store configuration data as name-value pairs. The most valuable part is that configuration is persisted, so it will be available across server restarts. You don't have to worry about how the portlet container is storing or retrieving configuration data. Another important point in the specification is that preferences attributes are user-specific. This means that you cannot design a portlet where changes made by an administrator are stored in PortletPreferences object and made available to all users (actually, some portlet vendors provide way to achieve this in a container-specific way).
We will make one more change to our HelloWorld portlet so that it remembers the userName even after a restart. Change HelloWorld.java like this:
protected void doView(RenderRequest request, 
  RenderResponse response)
  throws PortletException, IOException {
    response.setContentType("text/html");
    String userName =
      (String)request.getPreferences()
      .getValue("userName",null);
    if (userName != null)
          response.getWriter().println("Hello " + userName);
    else
      response.getWriter().println
        ("Go to edit mode and set name");
}
 
public void processAction(
  ActionRequest actionRequest, 
  ActionResponse actionResponse) 
  throws PortletException, IOException {
    String userName =
      actionRequest.getParameter ("userName");
    PortletPreferences pref =
      actionRequest.getPreferences();
    pref.setValue("userName",userName);
    pref.store();
    actionResponse.setPortletMode(PortletMode.VIEW);
}


We are not using the PortletSession object to store the userName attribute anymore. Inside processAction(), we first get the value of the userName attribute submitted by user, and set it in the PortletPreferences object by calling the method pref.setValue("userName",userName). The next step is to call the store() method on PortletPreferences, which saves the changes made in PortletPreferences to the persistence store.


There are a couple of important points to remember. First, you can modify PortletPreferences only inside of the processAction() method. Trying to call it during render() will result in an IllegalStateException. Secondly, if you don't call the store() method after changing PortletPreferences and before exiting the processAction(), then those changes will be discarded. The PortletPreferences interface also defines a reset() method, which can be used to reset values of preferences attributes to default values.

Caching

The portlet specification defines an expiration-based caching mechanism. This caching mechanism is per-portlet and per-client, with a restriction that cached content must not be shared across different user clients displaying the same portlet.


The way it works is that a portlet that wants its content to be cached using the content cache must define the duration of the expiration cache in a deployment descriptor, like this:
<portlet>
  <expiration-cache>300</expiration-cache>
</portlet>


Now suppose Portlet A has defined that it wants it content to be cached for 300 seconds and it is placed on a page along with Portlet B. If the user performs some action on Portlet B, the portlet container can choose to use cached content generated by Portlet A instead of calling its render() method again. But if the user performs some action on Portlet A, the container should invalidate the cached content of Portlet A and call its render() method once again.
Please note that it is not necessary for a portlet container to implement caching, and it can choose to disable caching any time it wants. But if the container does implement this feature, it helps improve portlet response time and reduce load on the server.

Conclusion

Portals strive to be the next-generation desktops for users. They will provide you with one desktop with different windows for all of the applications that you might need. It will be very easy for an administrator to apply policy on what you can or can not see. The administrator can also install or update new applications on the server and make those applications available to all users.
With JSR-168, one major hurdle of portlet technology advancement has been removed. Now if your portlet application is JSR-168-compliant, it can be deployed on any compliant server and it will appear as one window on the user's desktop.






The main new features of version 2.0 provide capabilities for coordination between different portlets that can be implemented by different parties and packaged in different WAR files. The coordination features of JSR 286 are based on a loosely coupled publish/subscribe model that does not require that the different portlet developers know about each other's work. At development time, you define only the data that a portlet understands, and the actual connections between portlets are created at deployment or runtime. Leveraging these coordination features, portal administrators or business users can now build larger composite applications, out of portlet components without programming. This capability opens the possibility to create new functionality by combining existing components into business mashups in a similar fashion to popular Web 2.0 usage – even in ways that the component authors may never have envisioned themselves.
JSR 286 defines two different means for coordination, addressing two different use cases:
  • Events. Support for active notifications with action capabilities to the portlet.
  • Public render parameters. Support for sharing of view state across portlets.
We explain both of these use cases in more detail in the following sections.

JSR 286 allows portlets to send and receive events. As mentioned before, the model is a loosely coupled model where the portal application acts as broker between the different portlets and distributes the events.

        <portlet>
               …
               <supported-publishing-event>
                       <qname xmlns:x="http://com.ibm/portal/portlets/ns">
x:city</qname>
               </supported-publishing-event>
        </portlet>
        <event-definition>
               <qname xmlns:x="http://com.ibm/portal/portlets/ns">x:city</qname>
               <value-type>java.lang.String</value-type>
        </event-definition>

You can specify a full QName for each event, or if you use the same namespace for many events, you can declare it as the default namespace and then specify only the local part of each event.
In addition to the name, you need to specify the type of the event payload to allow the portal application to serialize / deserialize the payload in the case that the portlets are using different classloaders or may even run as remote portlets using Web Services for Remote Portlets (WSRP). Thus, the requirement for the payload is that it is either a simple type (for example, String) or that it needs to be Java serializable and Java Architecture for XML Binding (JAXB) serializable. Why do we need this additional JAXB serialization? A portlet may want to send an event to a remote portlet that is running using WSRP. These remote portlets may not be written in Java, and so we need a more general mechanism than the Java serialization. JAXB allows serializing Java objects into XML; all you have to do is annotate your Java object accordingly.
This detail was the hard part; now your work is getting simpler: receiving and sending events through your portlet. You can send an event using the setEvent method on the ActionResponse or the EventResponse. To receive events you need either to extend GenericPortlet or to implement the EventPortlet interface yourself. Extending GenericPortlet has the additional advantage of being able to use annotations for denoting special methods for handling events, processing actions, and rendering a specific portlet mode.

        @ProcessEvent(qname="{http://com.ibm/portal/portlets/ns}city")
        public void cityEvent(EventRequest request, EventResponse response )
                                      throws IOException, PortletException
        {      
               Event ev = request.getEvent();
               if ( ev.getValue().equals("Orlando") ) {
                       ….
               }
               …
        }
       

Public render parameters allow sharing of request parameters across different portlets or other artifacts, like themes or portal pages in IBM WebSphere Portal. Defining a public render parameter is very similar to defining an event: You specify a unique QName and optional alias names in the portlet.xml deployment descriptor. The QName and alias names are used to connect public render parameters of different portlets. You can view these public render parameters as a shared storage area where all participating portlets can set and get the values.
 an example where a navigator portlet and a content portlet share the same public parameter docid. After you click a link in the navigator portlet that sets the docid to document3, the content portlet displays the content of that document because its view state (the ID of the current document) has been changed from an external influence. Note that public render parameters can be stored in the URL, as in the WebSphere Portal implementation, and thus you can bookmark pages and use the browser's Back and Forward buttons.
How can the portlet get access to these public render parameters? In the portlet itself, you access the public render parameters with the same methods that are used to handle ordinary render parameters defined in version 1.0. Given that these methods take only Strings as keys and not QNames you need to define an identifier in the portlet.xml that you can then use inside the portlet code for addressing the public render parameter.


In most cases, the portlet code does not actually need to change whether a render parameter is public or private, so you can enable your portlet for coordination by simply declaring those parts of the view state information in the portlet.xml that can reasonably be set from external sources as public parameters. If you want to specifically access only public render parameters in your code, then you can also use the method getPublicParameterMap on the request.

In the first version of the Java Portlet Specification, you could not serve dynamically generated resources directly through the portlet. Instead, you needed an additional servlet that served the resources. This limitation had some disadvantages:
  • You do not have the portlet context available, which means you have no access to render parameters, portlet mode, window state, portlet preferences, portlet session, and more.
  • URLs generated in the servlet are outside the portal scope and leave the portal experience. In addition, the current state of the portal page accumulated in the portal URL is lost.
  • The servlet does not run under the portal access control and needs to be secured separately.
One advantage of serving resources through a servlet is less overhead because the request does not have to pass through the additional portal framework, for example, when serving large media streams.

Version 2.0 now introduces a new URL type, resource URLs. Resource URLs trigger the lifecycle method, serveResource, on the ResourceServingPortlet interface that you can leverage to create dynamic resources directly in the portlet.

You must have a resource URL to trigger the new serveResource life-cycle method. Let's start by looking into the details of the new resource URL.

Resource URLs can be created similar to other portlet URLs, with the method createResourceURL on the RenderResponse and ResourceResponse, for example, ResourceURL url = response.createResourceURL();
Now you can set parameters on the URL as you do for other portlet URLs. You receive these parameters in the serveResource call. Note that ResourceURLs cannot set new render parameters, portlet mode, or window state. This restriction occurs because serveResource calls do not generate a full new portal page, but return the response of serveResource. Thus, the portal does not have a chance to update other parts of the page where this information may be encoded; for example, in WebSphere Portal all URLs contain this information and so need to be updated.

You can also set an additional resource ID on the resource URL that clearly identifies your resource. If you extend GenericPortlet, GenericPortlet tries to forward to that resource ID for a serveResource call. You can set the path to your resource asID, as shown here: url.setResourceID("WEB-INF/jsp/xmlcontent.jspx");
In this case, GenericPortlet automatically dispatches to the given JSP, which can then make use of the portlet state information by including the portlet tag library. Note that static resources like GIF files packaged in your portlet WAR should normally be referenced with static resource URLs such as: String url = response.encodeURL(request.getContextPath()+"/icons/myigif.gif");
Serving static resources using the portlet's serveResource method causes unnecessary performance overhead.
To receive a serveResource call triggered by a resource URL, you need to either implement the new ResourceServingPortlet or extend GenericPortlet, which already implements the new interface. In the serveResource call, you get a specific resource request / response pair.
The resource request has similar methods to the render request, but in addition it lets you get access to upload data. In the resource request, the parameter handling lets you have access to three different types of parameters:
  • Resource parameters set on the resource URL that are available only for this resource call, accessible through the getPrivateParameterMap call
  • Private render parameters of the portlet, accessible through the getPrivateRenderParameterMap
  • Public render parameters, accessible through the getPublicParameterMap call
The ordinary parameter access methods return the merged set of these three parameter maps. Parameters that have the same key first get the resource parameter values merged and then either the private or public render parameter values, depending on whether the parameter key was declared as a public render parameter in portlet.xml.
With resource URLs, you can leverage all HTTP methods, not only GET, as you do in render. This capability means that you can use methods such as POST or DELETE to change state in the serveResource call. These state changes, though, should be limited to private state of the portlet: portlet-scoped session data and portlet preferences. You should not modify state that affects other portlets because the portal framework does not have a chance to update other parts of the portal page for serveResource calls, so that updates to page-level state may not be visible.
NOTE: Render parameters, portlet mode, and window state fall into this category as some portal implementations, such as WebSphere Portal, store this information in the URL to support the ability to bookmark and the use of Back and Forward buttons in the browser. This implementation means that changing a render parameter, for example, requires an update of all the URLs on the page, which the portal cannot perform, as the processing of the response data on the client is done entirely by the portlet.
Because the markup returned from serveResource is not aggregated with other markup from the portal framework, the resource response allows full control over the output stream. For example, the portlet can set a HTTP status code.
There are many different use cases for serving resources; therefore, there are also different requirements for the ability to cache serveResource calls. You can influence the HTTP caching behavior of resource requests with the setCacheability method on the ResourceURL. This method gives a hint to the portal about how much information the target serveResource call requires. Therefore, the portal can remove irrelevant data from the URL, which results in more stable URLs and more HTTP caching hits for resource requests. Note that setting the cacheability of a resource response makes sense only if you allow the response to be cached by specifying HTTP caching headers for the returned response. This specification means that you must set at least an expiration time using response.getCacheControl().setExpirationTime(). If the returned content is not user specific, you should additionally set the cache control to public scope.
JSR 286 supports the following scenarios:
  • Full cacheable resources, which do not depend on interaction state. An example is a programmatically generated SVG view that depends on the portlet preferences for back-end access. To mark a serveResource call as fully cacheable, you need to set the cacheability on the resource URL to FULL. This setting means that the portal can generate a URL that does not contain any interaction state of the page and the portlets on the page. Thus, the browser can cache the returned markup of the serveResource call for at least as long as the user interacts with the current page.
As a result of not encoding any state of the page and portlets on the page, you cannot count on getting the current render parameters, portlet mode, or window state in your portlet. Keep in mind that because of the missing state information, you are restricted in the output of serveResource: You can include only resource URLs that are fully cacheable, and you cannot include action or render URLs.
  • Full and shared cacheable resources such as shared static resources, for example, JavaScript libraries. You can mark a FULL cacheable serve resource URL as shared by adding the additional SHARED property on the URL with the name of the shared resource as a value. The name should be a QName that identifies the resource uniquely, for example {http://dojotoolkit.org/v1.0}dojo.js.
Specifying the shared property enables the portal to use only one version of such shared resources per page. It still requires that the portlet packages these resources in its WAR file in case the portal has not already loaded the resource.
Leveraging portal resources that do not need to be provided by the portlet is vendor specific; for example, in WebSphere Portal you can use the ResourceURLAccessor to create resource URLs.
  • Portlet-level cacheable resource that depends on portlet interaction state, for example, a dynamically generated PDF output of the current portlet view. If you need to have access to the portlet state, for example the render parameter, portlet mode, or window state, but you are not going to put action or render URLs in your response or in later responses, you set the cacheability level to PORTLET. This level allows refreshing the resource for each interaction with the portlet, but also allows using the cached resource when interacting with other portlets on the page.
  • Page-level cacheable resources such as resources providing action or render URLs, for example, the markup returned for an Ajax call. PAGE-level cacheability is the default setting. You have no restrictions in your serveResource method, which means that you can generate action or render links. It also means that your resource cannot be cached across any interaction with the portal page that changes a part of the state of the page.
In summary, these cacheability levels give you the ability to provide as many hints about the cacheability as possible to the runtime. The runtime also can enhance the cacheability of resources in other ways, for example by keeping track of the state changes on the client and re-rendering only the parts affected by state changes. An example for this is the Client-side Aggregation theme in WebSphere Portal V6.1 Beta.
In version 1.0, support for Ajax use cases was rather minimal: You had only the ability to provide an additional servlet that serves the Ajax fragment. This servlet, however, was then addressed directly and not through the portal framework, so it did not have the portlet state provided, nor was it under the security protection of the portal, as you can see in figure 4 . The only way to share data between the portlet and the servlet is to use the application-scope session or the parameter on the URL that invokes the servlet.
How does the new portlet specification support Ajax use cases?
As we have seen, JSR 286 provides you with the means to serve resources directly using the portlet. Thus, you can issue XmlHttpRequests to ResourceURLs and, on the server side, get complete access to the portlet context such as render parameter, portlet mode, window state, portlet preferences, and portlet session.
We also learned that you can make some state changes in the serveResource call:
  • Change the portlet preferences
  • Change data in the portlet session scope
You can now implement additional use cases such as asynchronous updates that make your user interface more responsive.
 the solution in JSR 286. You can see that the Ajax calls go through the portal servlet and thus are under the control of the portal. You can also leverage resource URLs to provide the links to your JavaScript library.
The first version of the Java Portlet Specification restricted the portlet programming model in some areas compared to the servlet programming model. This restriction was done because portlets are aggregated on a page and all concepts that assume that you are the only component on the page are not easily applied to the portlet programming model.
The second version tackles these issues and provides solutions so that the portlet programming model has nearly the same capabilities as the servlet one, plus the portlet specific extensions.
In the first version of the Java Portlet Specification, the portlet could not contribute to sections of the portal page outside its portlet window. In the second version, you can set cookies, document head section elements (for example, HTML ones such as meta, link, or style) and HTTP headers (such as application-specific Pragma headers).
Two-part rendering life-cycle call
To overcome the problem that version 1.0 faced with contributing content outside the current portlet window, version 2.0 added a two-part render call:
  1. RENDER_HEADER part that allows the portlet to return content outside the current portlet window such as portlet title, preferred next possible portlet modes, cookies, document head section elements, and HTTP headers.
  2. RENDER_MARKUP part that allows the portlet to return its normal markup.
These two parts are needed as some portal implementations, such as WebSphere Portal, stream the page and portlet output directly to the client to avoid buffering overhead. In this case, the portlet rendering cannot add anything to the head section of the document, as the head section is already written. Thus, portlets that want to contribute to the head section or to set a portlet title should turn on the two-part rendering feature with the setting shown in listing 3 in the portlet deployment descriptor.
<portlet>
               <container-runtime-option>
                       <name>javax.portlet.renderHeaders</name>
                       <value>true</value>
               </container-runtime-option>
        </portlet>
       

Implementing two-part rendering is straightforward if you extend GenericPortlet and override the methods that GenericPortlet provides, such as getTitle and getHeaders. The GenericPortlet class does the rest for you.
Using cookies
You can set cookies at the response of each life-cycle method (processAction, processEvent, render, and serveResource) with this code: response.addProperty(javax.servlet.http.Cookie cookie)
The cookie can then be accessed in all life-cycle methods using: request.getCookies()
Using cookies in portlets is different from using cookies in servlets in these ways:
  • As mentioned, to set cookies in the render method, the renderHeaders option should be turned on and the cookies should be set in the RENDER_HEADERS part by using overriding doHeaders() of GenericPortlet, for example.
  • Cookies may not be accessible at the client because they are stored at the portal server or they are put in a different namespace when the portlet runs as a remote portlet through WSRP.
  • Cookies are not guaranteed to be shared across different portlets.
In the first version of the Java Portlet Specification, you had only the option of including servlets or JSPs from the render life-cycle call. The second version lets you use forward and include and lets you use them in all life-cycle methods.
This addition means that you can now dispatch to action or event logic written in a servlet, or you can do forwards when serving resources try to forward to the resource ID that you have set on a ResourceURL.
In V1.0, the servlet HttpSession listeners can be also used for the PortletSession as the PortletSession is a façade on top of the HttpSession. Version 2.0 extends the list to all servlet life-cycle listeners defined in the Java Servlet Specification V2.5, and it enforces a correspondence between portlet and servlet objects:
  • javax.servlet.ServletContextListener. For notifications about the servlet context and the corresponding portlet context.
  • javax.servlet.ServletContextAttributeListener. For notifications about attributes in the servlet context or the corresponding portlet context.
  • javax.servlet.http.HttpSessionActivationListener. For notifications about the activation or passivation of the HTTPSession or the corresponding PortletSession.
  • javax.servlet.http.HttpSessionAttributeListener. For notifications about attibutes of the HTTPSession or the corresponding PortletSession.
  • javax.servlet.http.HttpSessionBindingListener. For notifications about binding of the object to the HTTPSession or the corresponding PortletSession.
  • javax.servlet.ServletRequestListener. For notifications about changes to the HTTPServletRequest or the mirrored portlet request of the current Web application.
  • javax.servlet.ServletRequestAttributeEvent. For notifications about changes to the attributes of the HTTPServletRequest or the mirrored portlet request of the current Web application.
A servlet request listener can distinguish a plain servlet request targeted to a servlet from a wrapped servlet request targeted to a portlet by looking at the request attribute javax.portlet.lifecycle_phase. This attribute is set on a request targeted to a portlet, indicating the current portlet life-cycle phase of this request.
Access to all these life-cycle listeners gives you many hook points for managing objects related to these lifecycles, which is a great feature for many frameworks. These hook points, though, come with a cost, especially the request lifecycle listeners, which add significant processing overhead for each request. Therefore, use them with care.
The expert group of JSR 286 worked to make JSR 286 extensible so that you can add features and functionality in our frameworks on top of JSR 286 in a noninvasive and container-independent manner. You can add:
  • Servlet lifecycle listeners
  • Portlet filters for wrapping the request / response
  • PortletURL listeners for manipulating the URL before it is written to the output stream
  • Portlet-managed modes allowing the portlet to provide its own portlet modes
Some extension points require that the container supports this extension point for the portlet to take advantage of the extension. These extension points are:
  • Request / response properties from V1.0 for setting extension properties on request or response. Version 2.0 adds several new spec-defined extension properties, such as the predefined caching properties.
  • PortletURL properties for extending the PortletURL, for example, the predefined SHARED property for ResourceURLs.
  • Container runtime options for leveraging additional container behavior, such as the two-part rendering.
Let's take a deeper look into the new features for extending the Java Portlet Specification in the next sections.
The new portlet filter functionality allows you to plug filters around any life-cycle call of the portlet. Following the common decorator pattern, filters can do pre- or post-processing, and they can modify or wrap the request and response objects that are passed to the portlet. Typical applications of portlet filters could include these:
  • Passing information from additional sources to the portlet as attributes or parameters
  • Output filtering for security enforcement or markup compliance
  • Collecting diagnostic information
  • Bridging between Web application frameworks
WebSphere Portal V6.1, for example, uses a filter approach to augment the markup of portlets with additional semantic information for client-side click-to-action.
The portlet filter programming model is modeled on the servlet filter model:
  1. Define the filters in the deployment descriptor. This definition is done using the <filter> element, where you also need to state the life-cycle call to which the filter should be applied.
  2. Implement the corresponding Filter interface in your filter. You can also list multiple life-cycle entries and implement multiple Filter interfaces with your class.
  3. Provide a filter-mapping element where you describe to which portlets your filter should be applied (you can also use an asterisk as a wildcard if it should be applied to all portlets in the application).
The order of the filter-mapping elements in the deployment descriptor also defines the order of the filters that are applied to the portlet. Listing 4 shows an example for a deployment descriptor entry.
// filter declaration
<filter>
               <filter-name>PortletFilter</filter-name>
               <filter-class>com.example.PortletFilter</filter-class>
               <lifecycle>RENDER</lifecycle>
</filter>

// filter mapping             
<filter-mapping>
               <filter-name>PortletFilter</filter-name>
               <portlet-name>MyPortlet</portlet-name>
</filter-mapping>

At runtime, a filter chain of all the filters is applied to the portlet. Each filter gets the current request and response, or a wrapped version created by a preceding filter, and the filter chain. After doing its preprocessing, the filter implementation can either terminate the request processing or call the next element in the filter chain, passing in either the received request and response or additional wrappers. The last element in the filter chain is the portlet itself.
Listing 5 is an example of a filter that does some pre- and post-processing and provides the portlet with a wrapped request.
public class PortletFilter implements RenderFilter {

               public void doFilter(RenderRequest req,
         RenderResponse resp, FilterChain chain) throws .. {
                       PrintWriter pw = resp.getWriter();
                       pw.write("Pre-processing");

                       MyRenderResponseWrapper resWrapper =
                                      new MyRenderResponseWrapper(res);
                       chain.doFilter(req, resWraper);

                       pw.write("Post-processing");
               }
}

Note that when you use wrappers, you should stick to the wrapper pattern and only override existing behavior. Do not add new methods on the wrapper; there may be other wrappers in the chain that you don't know of, and thus the portlet may not be able to access your new method. If you want to provide the portlet with additional capabilities, set an object providing access to these capabilities as a request attribute.
In some cases, you may want to centrally manage setting specific properties on portlet URLs or to enhance the portlet URL creation of existing portlets. One example involves implementing a mapping of resources to shared IDs. You implement this mapping only once in the listener, and the listener checks if the resource URL is targeting a resource for which a shared QName exists and then sets the SHARED property with the corresponding QName. For these use cases, the JSR 286 specification gives you the portlet URL listeners.
You need to register such a listener with the listener element in the portlet deployment descriptor, and your class needs to implement the PortalURLGenerationListener interface that defines a callback method for each type of portlet URLs: action, render, and resource.
In JSR 168, the portlet could leverage only portlet modes that are supported by the portal framework running the portlet. In some use cases, the portlet wants to offer portlet-specific functionality with the same user look-and-feel as portlet modes supported by the portal (for example, with context menus on the portlet window). For example, a ShowShoppingCart portlet mode lists all entries that you currently have in your shopping cart.
To support these use cases, JSR 286 introduces the portlet-managed modes that are not known to the portal, but are managed by the portlet itself. The portlet can declare such a mode in the portlet deployment descriptor with the code shown in listing 6.
        <custom-portlet-mode>
               <description>Show shopping cart</description>
<portlet-mode>ShowShoppingCart</portlet-mode>
                <portal-managed>false</portal-managed>
        </custom-portlet-mode>

The important point here is to set the portal-managed mode to false. This setting indicates to the portal that it should treat this mode just like the standard View mode concerning all aspects, including how it provides the portlet with preferences and from the perspective of access control. The portal should provide UI controls that allow the portlet to switch to this mode. The portlet can define localized names for the decoration using the resource bundle entry: javax.portlet.app.custom-portlet-mode.<name>.decoration-name.
Because the portal does not know specific semantics of the portlet-managed modes, it does not know when it makes sense to present a decoration to switch to a portlet-managed mode and when it does not. Therefore, the JSR 286 specification lets you indicate for which portlet modes the portal should display UI controls as part of the render response using the method setNextPossiblePortletModes. When you use GenericPortlet, you can override getNextPossiblePortletModes, and GenericPortlet takes care of setting these in the RENDER_HEADER part. Note that you need to set this list of modes on each response and that you should enable the container runtime option javax.portlet.renderHeaders mentioned in the next section.
Container runtime options allow the portlet to supply specific options to the portlet container that either change default behavior defined in the Java Portlet Specification or add additional behaviors. We've already seen an example of such a container runtime setting: the renderHeaders option. JSR 286 defines a list of container runtime options that are all optional except for actionScopedRequestAttributes. In addition to these options, specific portlet container implementations may provide their own options.
You indicate that your portlet requires a specific container runtime option in the deployment descriptor using the code shown in listing 7.
<portlet>
               <container-runtime-option>
                       <name>NAME_OF_THE_OPTION</name>
                       <value>optionally you can have one or more parameters</value>
               </container-runtime-option>
        </portlet>

These options are predefined in JSR 286:
  • javax.portlet.escapeXml. Allows you to turn off the XML escaping of portlet URLs for each default, in case you have written a JSR 168 portlet that assumes that URLs are not XML escaped and have migrated this to a JSR 286 portlet.
  • javax.portlet.renderHeaders. Enables the two-part rendering mechanism that lets you set headers in streaming-based portal implementations.
  • javax.portlet.servletDefaultSessionScope. Allows you to change the default scope of the session object provided to servlets or JSPs that are called from the portlet through forward or include from application scope to portlet scope. That way, these resources access the same session data using portlet and servlet APIs, which is particularly convenient if your JSPs are written for a servlet-based Web framework.
  • javax.portlet.actionScopedRequestAttributes. Allows Web frameworks to pass complex objects from the action or event phase to the render phase through the request. You are able to access these attributes until the next request with an action semantic (which may be an action triggered through an Action URL or an event) occurs. This feature likely is implemented by the portlet container by storing these attributes in the session. Therefore, use this feature only if you cannot avoid it, as it will probably cause some performance degradation. This option is the only one that JSR 286 requires to be supported by all containers.
Note that if you use a container runtime option and the container on which your portlet is deployed does not support this option, the container may reject the deployment of the portlet. Use these options with care if you want to develop a portlet that can run on many different portlet container implementations.
Java Portlet Specification V2.0 was designed to avoid breaking binary code compatibility with V1.0 and to maintain compatible behavior for all API methods. This design point means that all portlets written against the V1.0 specification should run unchanged on a V2.0 container. The only exceptions to this rule are the following slight behavior changes that normally should not break any portlets:
  • RenderResponse.setContentType is no longer required before calling getWriter or getOutputstream. Calling getWriter or getOutputstream without previously setting the content type no longer results in an IllegalStateException in V2.0.
  • getProtocol for included servlets / JSPs no longer returns null, but instead returns HTTP/1.1 in V2.0.
This backward compatibility statement also includes the deployment descriptor in which V2.0 added new entries, but did not change existing ones. This behavior means that you can turn most JSR 168 portlets into a JSR 286 portlet by changing the one line in the portlet deployment descriptor that references the schema to the new V2.0 portlet deployment descriptor schema.
In this section, we cover various smaller additions that can make your life easier and that can support new use cases, such as the new Java 5 features leveraged in the API, the new caching features, the changes in the runtime IDs that you can access, and the tag lib additions.
JSR 286 leverages some of the new Java 5 features:
  • Using Generics
  • Introducing a new enum class for all user profile attributes
GenericPortlet also lets you use the following annotations to make dispatching life-cycle calls to specific handler code easier:
  • ProcessAction. This annotation allows you to annotate a method that should process a specific action. To allow dispatching, the Action URL needs to include the parameter javax.portlet.action.
  • ProcessEvent. This annotation allows you to annotate methods that should process specific events.
  • RenderMode. This annotation allows you to annotate methods that should render a specific portlet mode.
Listing 8 shows how you use the ProcessAction annotation.
    // generating the URL
    PortletURL url = response.createActionURL();
    url.setParameter(ActionRequest.ACTION_NAME, "actionA");
    url.write(output);

    // method for handling the action
    @ProcessAction(name="actionA")
    void processMyActionA(ActionRequest req, ActionResponse resp)
    throws PortletException, java.io.IOException; {
    …
    }

Because some portal implementations still depend on Java 1.4, only features that can easily be removed for Java 1.4-based platforms have been added to JSR 286. For Java 1.4-based platforms, a JAR file of the JSP 286 APIs compiled with Java 1.4 compliance settings in which the preceding features have been removed.
JSR 286 adds new caching features that help making portlets scale better:
  • Public caching scope, which marks cache entries shared across users
  • Support for multiple cached views per portlet
  • Validation-based caching for validating expired cache entries
In JSR 168, all cache entries were private for each user. If you have portlets that are not customizable and don't display different content for different users, such as a news-of-the-day portlet, then you get a cache entry for each user, even if all entries are the same. Now, in JSR 286, you can tell the portlet container that the cache entry can be shared using the cache-scope element in the deployment descriptor. Thus, you can dramatically reduce the memory footprint for these portlets, as the code in listing 9 shows.
<portlet>
               ...
               <expiration-cache>60</expiration-cache>
               <cache-scope>public</cache-scope>
                ...
        </portlet>
 

A portlet can also set the cache scope programmatically using a response property or the new CacheControl interface. We recommend that you do not change the cache scope programmatically, though, as it may be difficult for portlet containers to ensure that cache entries are invalidated correctly if your portlet mixes responses with cache scope public and private for the same user.
The JSR 168 specification demanded that portlet containers must invalidate the cache for each user interaction with a portlet (render or action URL), so that there could be only a single cache entry per portlet window and user. With the introduction of public render parameters and shared caching, the specification has been enhanced to allow the container to cache multiple portlet views based on render parameters. This enhancement means that you can use render parameters so that users can navigate between different views in a shared cacheable portlet while the output still remains cached. Only the action and event processing calls, which can cause side-effects that are not known to the container, now require a cache invalidation.
Validation-based caching is useful for situations in which you do not want to recompute the markup of a portlet often because it is an expensive operation. Ideally, set the expiration time to a high value so that the markup is cached for a long time. On the other hand, you may want to respond quickly to changes in your back-end system and provide an updated view of the portlet. Validation-based caching solves this dilemma: It allows you to define a short expiration time so that your portlet gets called often and can check for changes in the back-end system. If nothing has changed in the back-end system, you validate that the expired cache content is still valid to use by setting the CacheControl. setUseCachedContent(true) and setting a new expiration time. If something has changed in the back-end system, then you produce new markup and set the setting to false.
How do you know which back-end state the currently cached markup maps to? You can set a specific validation token, called ETag after the same tag in the HTTP specification, on the response. The portlet container can then provide you with this ETag in the request of the next render or serveResource call, indicating that it still has the cached content available, which can be revalidated.
An example of using validation-based caching is shown in listing 10.
protected void doView (RenderRequest request, RenderResponse response)
    throws PortletException, java.io.IOException
{
       if ( request.getETag() != null ) {  // validation request
        if ( markupIsStillValid(request) {
               // markup is still valid
               response.getCacheControl().setExpirationTime(30);
               response.getCacheControl().setUseCachedContent(true);
               // no need to write any output
               return;
        }
   }
   // create new content with new validation tag
   response.getCacheControl().setETag(computeETag(request));
   response.getCacheControl().setExpirationTime(60);
   PortletRequestDispatcher rd =
   getPortletContext().getPortletRequestDispatcher("jsp/view.jsp");
   rd.include(request, response);
}

private boolean markupIsStillValid(PortletRequest request) {
    // check if backend state still matches validation token
    return computeETag(request).equals(request.getETag())
}

private String computeETag(PortletRequest request) {
    // return some backend state indicator like a last update timestamp
}

Using validation-based caching is beneficial only if the operations for creating the markup are expensive compared to the operations for checking the back-end state. If, for example, the request to the back-end server takes up 90 percent of the time to render the portlet, it does not make sense to use validation-based caching to save only the remaining 10 percent rendering time.
Runtime IDs can be used to scope data that your portlet handles, so that you can avoid collisions between multiple occurrences of a portlet within the same portal, and maybe even on the same page. Most portlet API objects, for example, portlet session or portlet preferences, do implicit namespacing, but you need to do explicit namespacing when you access shared data stores or want to assign unique IDs to output elements. This practice is common for Ajax applications, which can particularly benefit from the two enhancements that version 2.0 provides in this area.
First, JSR 286 extended the lifetime of the namespace runtime ID, using the response.getNamespace method, from being valid for only one request to now being stable for the lifetime of the portlet window. This extension now allows you to use the namespace to also crate namespace form IDs if, for example, your portlet is intended to be aggregated in a forms-based portal server. You can also leverage the namespace for JavaScript function calls that are embedded in Ajax responses, and you can reuse namespaced JavaScipt functions provided by a previous render call.
Second, JSR 286 introduced a new API call that allows you to get to a unique ID for the portlet window using the request.getWindowID method. This call now allows you to use this ID as key for data that you want to create namespace per portlet window; for example, the portlet wants to cache data that it received from a back-end system per portlet window. Note, however, that no life-cycle calls are defined around the portlet window, so if you use the portlet window ID for specifying namespace entries in a persistent data store, you also need to clean up these entries yourself.
The JSR 286 tag library has its own namespace so that new additions do not interfere with portlets using the old JSR 168 tag library. You now need to include the new tag library with: <%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
The define objects tag is now enhanced and gives you the following additional variables beyond the request, response, portletConfig from the V1.0:
  • portletSession.For access to the portlet-scoped session.
  • portletSessionScope. For access to the portlet-scoped session attribute key/values map.
  • portletPreferences. For access to the portlet preferences.
  • portletPreferencesValues. For access to the portlet preferences key/values map.
Each of the URL generation tags has the following additional attributes:
  • copyCurrentRenderParameters. For copying the current private render parameters to the URL.
  • escapeXml. For turning the default XML escaping of the URL. As mentioned previously, in JSR 168 it was not defined if a URL is XML-escaped or not. JSR 286 now has defined the same behavior as the Java Standard Tag Library: by default all URLs are escaped, but you can turn it off using the escapeXml attribute.
For action URLs, there is also the additional name attribute that allows you to set the javax.portlet.action parameter that is evaluated by the GenericPortlet for dispatching to the ProcessAction annotated methods.
Other additions made in the JSR 286 specification include these:
  • Adding a new resourceURL tag for generating resource URLs
  • Adding the new propertyTag that can be used inside portlet URL tags for attaching properties to URLs
As you have seen, the second version of the Java Portlet Specification added a lot of new content and abilities. The specification and the APIs more than doubled compared to version 1.0. Now the Java Portlet Specification has grown up, and it allows you to implement most use cases without the need to have vendor extensions. Note that some of the features described in this article are optional, so they may not be supported on all JSR 286-compliant platforms, but the standard ensures that those platforms that provide extended capabilities do so in a consistent and well-defined manner.
The portlet programming model now provides you with events and public render parameters so that you can build larger composite applications out of your portlets and reuse your portlets in different scenarios. Finally, you get better support for Ajax-based use cases with JSR 286 as you are now able to serve resources directly though the portlet.


Portlet Eventing 286
<portlet>
               …
               <supported-publishing-event>
                       <qname xmlns:x="http://com.ibm/portal/portlets/ns">
x:city</qname>
               </supported-publishing-event>
        </portlet>
        <event-definition>
               <qname xmlns:x="http://com.ibm/portal/portlets/ns">x:city</qname>
               <value-type>java.lang.String</value-type>
        </event-definition>
--------------------à
@ProcessEvent(qname="{http://com.ibm/portal/portlets/ns}city")
        public void cityEvent(EventRequest request, EventResponse response )
                                      throws IOException, PortletException 
        {       
               Event ev = request.getEvent();
               if ( ev.getValue().equals("Orlando") ) {
                       ….
               }
               …
        }

Listener
  • javax.servlet.ServletContextListener. For notifications about the servlet context and the corresponding portlet context.
  • javax.servlet.ServletContextAttributeListener. For notifications about attributes in the servlet context or the corresponding portlet context.
  • javax.servlet.http.HttpSessionActivationListener. For notifications about the activation or passivation of the HTTPSession or the corresponding PortletSession.
  • javax.servlet.http.HttpSessionAttributeListener. For notifications about attibutes of the HTTPSession or the corresponding PortletSession.
  • javax.servlet.http.HttpSessionBindingListener. For notifications about binding of the object to the HTTPSession or the corresponding PortletSession.
  • javax.servlet.ServletRequestListener. For notifications about changes to the HTTPServletRequest or the mirrored portlet request of the current Web application.
  • javax.servlet.ServletRequestAttributeEvent. For notifications about changes to the attributes of the HTTPServletRequest or the mirrored portlet request of the current Web application.




Filter
// filter declaration
<filter>
               <filter-name>PortletFilter</filter-name>
               <filter-class>com.example.PortletFilter</filter-class>
               <lifecycle>RENDER</lifecycle>
</filter>
 
// filter mapping              
<filter-mapping>
               <filter-name>PortletFilter</filter-name>
               <portlet-name>MyPortlet</portlet-name>
</filter-mapping>


public class PortletFilter implements RenderFilter {
 
               public void doFilter(RenderRequest req, 
         RenderResponse resp, FilterChain chain) throws .. {
                       PrintWriter pw = resp.getWriter();
                       pw.write("Pre-processing");
 
                       MyRenderResponseWrapper resWrapper = 
                                      new MyRenderResponseWrapper(res);
                       chain.doFilter(req, resWraper);
 
                       pw.write("Post-processing");
               }
}


String DATASOURCE_CONTEXT = "comp";
      Connection result = null;
      try {
      Context initialContext = new InitialContext();
      if ( initialContext == null){
      out.println("JNDI problem. Cannot get InitialContext.");
      }
      DataSource datasource = (DataSource)initialContext.lookup(DATASOURCE_CONTEXT);
      if (datasource != null) {
      result = datasource.getConnection();
      out.println("Lookup datasource.");
      Statement stmt = result.createStatement();
      ResultSet rs = stmt.executeQuery("select * from employee");
      while(rs.next()){
      out.println (rs.getString(1));
      out.println (rs.getString(2));
<portlet>
                                <portlet-name>TwoP2</portlet-name>
                                <display-name xml:lang="en">TwoP2</display-name>
                                <display-name>TwoP2</display-name>
                                <portlet-class>com.ibm.twop.TwoP2Portlet</portlet-class>
                                <init-param>
                                                <name>wps.markup</name>
                                                <value>html</value>
                                </init-param>
                                <expiration-cache>0</expiration-cache>
                                <supports>
                                                <mime-type>text/html</mime-type>
                                                <portlet-mode>view</portlet-mode>
                                </supports>
                                <supported-locale>en</supported-locale>
                                <resource-bundle>com.ibm.twop.nl.TwoP2PortletResource</resource-bundle>
                                <portlet-info>
                                                <title>TwoP2</title>
                                                <short-title>TwoP2</short-title>
                                                <keywords>TwoP2</keywords>
                                </portlet-info>
                </portlet>
               
</portlet-app>

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Portlet Description Content 

Portal: a portal can be thought of as a Web-based application that is customizable by the end-user both in the look and feel of the portal and in the available content and applications which the portal contains. A portal, furthermore, can be thought of as an aggregator of content and applications or a single point of entry to a user's set of tools and applications

Portlet
The Portlet specification defines a portlet as a "Java-technology-based web component, managed by a portlet container that processes requests and generates dynamic content."

"Portlets are web components--like servlets--specifically designed to be aggregated in the context of a composite page. Usually, many portlets are invoked to in the single request of a portal page. Each portlet produces a fragment of markup that is combined with the markup of other portlets, all within the portal page markup."
In order to understand what a portlet is, it is very necessary to understand what a portal is. According to the Portlet Specification, "a portal is a web application that commonly provides personalization, single sign on, content aggregation from different sources, and hosts the presentation layer of information systems. Aggregation is the act of integrating content from different sources within a web page."
Portlet container: A portlet container is very similar to a servlet container, in that every portlet is deployed inside a portlet container that controls the life cycle of the portlet and provides it with necessary resources and information about its environment. A portlet container is responsible for initializing and destroying portlets and also for passing user requests to it and collecting responses.

Content aggregator: As defined in the Portlet Specification, one of the main jobs of a portal is to aggregate content generated by various portlet applications. We will talk more about this in the "How a Portal Page is Created" section.

Common services: One of the main strengths of a portal server is the set of common services that it provides. Services are not part of the portlet specification, but commercial portal implementations provide a rich set of common services to distinguish themselves from their competitors. A few common services that you can hope to find in most implementations are:
·         Single sign on:
·         Personalization
·         There are a few more common services such as machine translation, in which case the portal server will take content generated by portlet in one language and machine translate it into a language requested by user. Most of the commercial portal servers provide access via handheld devices and are capable of generating different content for different browsers.
Similar to servlets, portlets are web components that are deployed inside of a container and generate dynamic content. On the technical side, a portlet is a class that implements the javax.portlet.Portlet interface and is packaged and deployed as a .war file inside of a portlet container.
Portlets are similar to servlets, in that:
1. Portlets are managed by a specialized container.
2. Portlets generate dynamic content.
3. A portlet's life cycle is managed by the container.
4. Portlets interact with web client via a request/response paradigm.
Portlets are different from servlets, in that:
1. Portlets only generate markup fragments, not complete documents.
2. Portlets are not directly URL addressable. You cant send somebody URL of a portlet. You can send him the URL of the page containing a portlet.
3. Portlets cannot generate arbitrary content, since the content generated by a portlet is going to be part of portal page. If a portal server is asking for html/text, then all portlets should generate text/html content. On the other hand, if the portal server is asking for WML, then each portlet should generate WML content.
What Is a Portlet:

Portlets do provide some additional functionality.
  1. Persistent storage for preferences: Portlets provide a PortletPreferences object for storing user preferences. These preferences are stored in a persistent data store, so they will be available across server restarts. As a developer, you don't have to worry about the actual implementation of how it is stored.
2.    Request processing: Portlets provide much more refined request handling. A portlet may get a request when user takes some action on it (a state called action phase), or because the user took action on some other portlet and the page needs to be refreshed. A portal server provides different callback methods for handling both situations.
3.    Portlet modes: Portlets use a concept of mode to indicate what user is doing. When using a mail application, you may be using it for reading, composing, or checking mail messages--this is the expected functionality of a mail application. Portlets normally provide this in VIEW mode. But there are other activities, like specifying a refresh time or (re-)setting the username and password. These activities allow the user to configure the behavior of the application, so they come under EDIT mode. Help functionality of the mail application comes under HELP mode.
If you think about it, you will find none of these represents new functionality. Instead, most of these are common business requirements. The only thing the portlet specification is doing is providing you one layer of abstraction, so that it will be useful for all stake holders end users, developers and administrators.
As a developer, I put all my business logic related to VIEW mode in a method called doView(), and I put business logic related to the configuration of my application in a doEdit() method, with help-related logic in a doHelp() method.
This makes it simple for an administrator to control access in the portlet application, because all he has to do is change access rights of the portlet to dictate what things a user is allowed to do. For example, a user of a mail application is supposed to specify his username and password in EDIT mode, so it makes sense for him to have access to EDIT mode.
But consider the case where I am the administrator of an intranet site and my company bought a third-party portlet application that displays news updates. This application allows a user to specify the URL from where it can retrieve updates. I want to use this application for displaying internal company news to users. Another requirement is that I don't want users to use this application for tracking any other news source. So as the administrator, I can specify the URL of an internal news update site for all users, and take out their edit privileges by changing the deployment descriptor of this portlet application.
Using portlets makes my website much more appealing to the end user because she will get a similar UI for all her portlet applications. If she wants to read help information about any of the applications, she can click the help button. She will also know that clicking on an edit button will take her to a configure screen for that application. Standardizing the user interface will make your portlet application more appealing.
4.    Window state: The window state determines how much space should be given to content generated by a portlet on a portal page. If you click on the maximize button, the portlet will take up the entire screen and it will become the only portlet that will be available to the user. In minimized state, the portlet will be displayed as only a title bar. As a developer, you should customize your content based on the space available to you.
5.    User information: Commonly, portlets provide content personalized to the user making the request. To do this effectively, they may require access to user attributes such as name, email, phone, etc. The Portlet API provides the concept of user attributes for this. A developer can access these attributes in a standard way, and it is the responsibility of the administrator to map these attributes to an actual user information repository (usually an LDAP server).

JSR 168 & JSR 286
The Java Portlet Specification (JSR-168), approved in October of 2003, defines a standard API for J2EE-based portal platforms. The goal of JSR-168 is to provide a set of standards so that any compliant portlet can be deployed on any portal which supports the specification


Comparing common portlet API concepts

For both portlet APIs, there is one portlet object instance per portlet configuration in the Web deployment descriptor. The APIs differ in how each portlet object is represented in the portal.
Logical representation of portlets in the IBM portlet API
The PortletSettings object ( 1 ) provides the portlet with its unique set of configuration parameters and values. Configuration parameters are initially defined in the portlet deployment descriptor, but can also be added or modified by the portal administrator. There can be many PortletSettings objects, parameterizing the same portlet object according to the Flyweight pattern, provided on a per-request basis. Each PortletSettings object along with the portlet object comprises a concrete portlet.
Logical representation of portlets in the IBM portlet API
When users edit the settings in a portlet according to their preferences, the settings are saved to persistence using the PortletData object ( 2 ). There can be many PortletData objects parameterizing the same concrete portlet. Each PortletData object along with the concrete portlet comprises a concrete portlet instance.
When multiple users interact in different browser sessions with the same concrete portlet instance on a portal page, each user sees a particular user portlet instance, which is a concrete portlet instance parameterized with the session, a mode and window state ( 3 ).
Logical representation of portlets in JSR 168
In WebSphere Portal, JSR 168 portlets, like IBM portlets, can also be configured on two levels, by an administrator and by individual users. However, JSR 168 has no concept of a concrete portlet application or concrete portlets. The number of configuration layers is opaque to the programming model; the portlet configuration is contained within a single PortletPreferences object which aggregates these configuration layers.
Preferences can be marked in the portlet.xml as read-only so that they may be customized only by administrators ( 1 ) using configure mode or through the administration portlets. Preferences that are not marked read-only can be modified by users in edit mode ( 2 ).
The parameterized view of a portlet for an individual user interaction is called portlet window in JSR 168. JSR 168 adds render parameters as a new way to hold interaction state for a portlet window. A portal page can contain more than one portlet window for a single portlet, each portlet window associated with unique portlet mode, state, and render parameters ( 3 ).
Logical representation of portlets in the JSR 168 portlet API

Comparing elements of the API

Utility classes
The Portlet interface is the main abstraction for both the Java Portlet Specification and the IBM Portlet API. Portlets for both APIs should extend the corresponding utility classes, which provide default functionality for the portlet.
·         JSR 168 compliant portlets should extend the GenericPortlet class.
·         IBM portlets should extend the PortletAdapter class.
Life cycle
The following table compares the portlet life cycle between IBM portlets and JSR 168 compliant portlets.
IBM Portlet API
JSR 168
Description
init()
init()
Called after the portlet has been loaded and instantiated. Portlets use this method to perform one-time operations, especially those that might incur performance costs. The portlet can access its configuration, including initialization parameters, within this method.
initConcrete()
none
JSR 168 does not have a concept of a concrete portlet.
service()
render()
Used to render output to the client. These methods are typically applied using the mode-specific implementations of doView(), doEdit(), and doHelp(). In JSR 168, this method is invoked when the portal receives a render request.
none
processAction()
Used by the portlet to received parameters, update state, and perform any other necessary action processing. This is not part of the life cycle of the IBM portlet because the IBM portlet must implement an ActionListener for its counterpart, actionPerformed(), to be called. This method is invoked when the portal receives an action request.
destroyConcrete()
none
JSR 168 does not have a concept of a concrete portlet.
destroy()
destroy()
Called when the portlet is to be removed from service().
Request handling
Similar to servlets, portlets interact with clients using a request/response paradigm implemented by the portlet container. In a typical scenario, a user selects a page and the portlet container sends the request to each portlet on that page to render output in its response. These requests are called render requests. Other requests, however, are launched when the user interacts with one of the portlets on the page, such as clicking a submit button. Such actions generate URLs to the portlet, which might require the portlet to process an action before sending the response. These are called action requests.
In the servlet model, all request handling would be performed in the service() method. Portlets, however, use a two phase processing that is split between an event phase and a render phase. If the portlet receives an action request, then the event phase is started in which the portlet's action processing method is called. The result of this action could invoke actions for other portlets on the page. After actions have been complete for all portlets on the page, each portlet's rendering method is called. The event phase is guaranteed to complete before the start of the render phase.
The following table describes the differences between the IBM Portlet API and the Java Portlet Specification for handling requests.
IBM Portlet API
JSR 168
The portlet must implement an ActionListener to participate in the event phase. The actionPerformed() method is invoked to handle action requests. Request and session attributes can be set in the action and retrieved from the subsequent render phase.
During the render phase, the service() method is called. Methods for both phases take the same PortletRequest and PortletResponse objects as arguments. There is no distinction in the API between action request and response objects and render request and response objects.
The processAction() method is invoked to handle action requests. The main difference is that the action request and response objects are different from render request and response objects. The portlet can set render parameters or session attributes during the action that are available in the render call, but request attributes are not transferred between action and render phase.
For both APIs, if the portlet extends the appropriate utility class, the service() method dispatches the doView(), doEdit() or doHelp() methods, depending on the current portlet mode.
Portlet mode
Modes allow portlets to provide different interfaces depending on the task that is required of them. The following modes are supported by both APIs.
View
View mode is used for displaying portlet content. Utility class invokes doView() method.
Edit
Edit mode is used for personalizing the portlet (portlet data). Utility class invokes doEdit() method.
Help
Help mode is used for displaying help on the portlet Utility class invokes doHelp() method.
The following table describes support for other modes in each API.
IBM Portlet API
JSR 168
Configure mode is used by an administrator for globally configuring the portlet (portlet settings). Changes affect all occurrences of the portlet on all pages. Utility class invokes doConfigure() method.
Config mode supported as a custom mode. In config mode, the administrator can globally update the configuration of a portlet, including portlet's read-only preferences. Changes affect all occurrences of the portlet on all pages. In config mode, the portlet's read-only preferences can be updated by the administrator.
No custom modes.
Allows portlets and portal server implementations to support custom modes. At runtime, portlets use PortalContext.getSupportedPortletModes() to retrieve the modes supported by the portal and adapt accordingly. JSR 168 also suggests these custom portlet modes: about, config, edit_defaults, preview, and print. Vendors can also define other portlet modes.
The current portlet container in WebSphere Portal does not support any custom modes other than config mode.
Portlet window states
Window states indicate the amount of space that the portlet consumes on a page. The portlet can query its state to determine the visible size of the content it should render. The following states are supported by both APIs.
Normal
The portlet is provided equivalent space as other portlets on the page or in the same container.
Maximized
No other portlets are displayed, providing maximum space for the portlet's use.
Minimized
Only the portlet's title bar is displayed. The Java Portlet Specification allows the portlet to provided a limited amount of output, but for WebSphere Portal, the portlet's output is not displayed at all.
The following table describes support for other states in each API.
IBM Portlet API
JSR 168
Solo
Supported only as a custom window state. WebSphere Portal does not support solo state for JSR 168 portlets.
No custom states.
Allows portlets and portal implementations to define custom window states. At deployment time, the portal can map custom portlet window states from the portlet descriptor to its own custom window states, or it can ignore them. At runtime, portlets use PortalContext.getSupportedWindowStates() to retrieve the modes supported by the portal and adapt accordingly.
WebSphere Portal does not support custom window states for JSR 168.
Portlet URLs
Portlet URLs allow the portlet to create a URL to itself. When the user clicks a link or performs an action that launches the URL, it creates a new request to the portal targeted to the portlet. The following table describes how each API implements this functionality.
IBM Portlet API
JSR 168
PortletResponse.createURI() creates a URI to the portlet. An action can be set on the PortletURI object, so that the actionPerformed() method of the portlet is called before the service() method.
RenderResponse.createRenderURL() creates an URL that triggers the render() method of the portlet.
RenderResponse.createActionURL() creates an URL that triggers the processAction() method of the portlet before the render() method.
HTML form processing must be done using an action URL. Render and action parameters are separate for JSR portlets; parameters set on an action URL are not available to the render() method unless they are passed explicitly using ActionResponse.setRenderParameter().
See Request handling for details about the action and render method.
Namespace encoding
Portlets must contribute identifiers and names in their portlet output that is unique within the portal page. For example, two portlets could appear on a page, both with an anchor named return. Namespace encoding allows the portlet to ensure these names do not clash by adding the portlet's namespace to the anchor name. The following table shows how namespace encoding is performed in the Java source for each API.
IBM Portlet API
JSR 168
PortletResponse.encodeNamespace(name)
RenderResponse.getNamespace(name) returns a namespace that is valid for the current user session.
See JSPs for a comparison of how namespace encoding is performed for JSPs.
JSPs
The following table compares how JSPs are invoked from the portlet class for each API.
IBM Portlet API
JSR 168
PortletContext.include()
PortletRequestDispatcher.include()
The request dispatcher serves as a wrapper for a resource at the path indicated by getRequestDispatcher(path).
The following table describes the differences in the tag libraries for each API.
IBM Portlet API
JSR 168
<portletAPI:init/> - provides access to the PortletRequest, PortletResponse, and PortletConfig objects.
<portlet:defineObjects/> - provides access to the RenderRequest, RenderResponse, and PortletConfig objects
<portletAPI:createURI/>
Creates a URI that points to the portlet. To invoke an action in an IBM portlet, include the <portletAPI:URIAction/> tag and action parameters.
<portlet:renderURL/> creates an URL that will trigger the render() method of the portlet. <portlet:actionURL/> creates an URL that will trigger the processAction() method of the portlet before the render() method. See Portlet URLs for more information on render and action URLs.
<portletAPI:encodeNamespace/>
<portlet:namespace/> returns a namespace that is valid for the current user session.
Other tags provided by the IBM portlet API tag library
Use JSTL tags
URLs to portlet resources
In WebSphere Portal, resources within a portlet cannot be invoked using relative URLs. For URLs to these resources to work, they must be encoded using the encodeURL() method of the portlet response. Resources include any file in the portlet application that is referenced or invoked from the portlet or one of its JSPs, including:
·         images
·         applets
·         multimedia
·         JSPs
·         servlets
The following table explains the differences between each API for using the encodeURL() method.
IBM Portlet API
JSR 168
Use the encodeURL() method of the response and specify the path to the resource, for example:
<%= portletResponse.encodeURL("/images/photo01.jpg") %> 
Use the encodeURL() method, just as you would with the IBM portlet, except that you also have to add the context path of the portlet from the request, as in:
<%= portletResponse.encodeURL(renderRequest.getContextPath() 
     +  "/images/photo01.jpg") %> 
Caching
Both APIs provide the means for portlets to cache their output and improve performance and response times. The table below describes the differences in the implementations.
IBM Portlet API
JSR 168
Expiration timer set in the portlet.xml. The IBM Portlet API supports invalidation-based caching. Can be dynamically changed by the portlet when its getLastModified() method is called.
Expiration timer set in the portlet.xml. Can be dynamically changed by the portlet using the EXPIRATION_CACHE property of the RenderResponse.
Portlet configuration
For both APIs, the PortletConfig object is made available to portlet during initialization.
IBM Portlet API
JSR 168
Provides the initialization parameters defined in the web.xml. Initialization parameters can be read using the getInitParameter() method of the Portlet interface.
Provides the initialization parameters, which can be defined in the portlet.xml or the web.xml. Initialization parameters can be read using the getInitParameter() method of the PortletConfig interface.

Concepts unique to JSR 168

  • Render parameters
These are parameters attached to the render request that stay the same for every render request until a new action occurs. This allows storing navigational state in the render parameters instead of the session. The portlet should put all state information it needs to redisplay itself correctly into render parameters (for example, which screen to render). This facilitates saving bookmarks and provides better support for the use of the browser's back button.
When the portlet is the target of an action, render parameters are reset. In the action, the portlet can set new render parameters to represent the new navigational state after the action is completed. The developer can use render URLs (see RenderResponse.createRenderURL()) to set render parameters directly without having to go through an action. As render parameters may be bookmarked, portlets should be prepared to handle parameters that are not valid (for example, that could be the result of an outdated bookmark). Such parameter values should be handled gracefully and should not lead to exceptions.
From the JSP, the portlet can set render parameters using the <portlet:renderURL/> tag.
  • Portal context
To allow portlets to adapt to the portal that is calling them, JSR 168 provides the PortalContext to be retrieved from the request. This portal context provides information such as the portal vendor, version, and specific portal properties. This allows the portlet to use specific vendor extensions when called by the portal of that vendor and fall back to some simpler default behavior when called by other portals.
As the portal context is attached to the request, it may change from request to request. This can be the case in the remote scenario, where one portlet (WSRP provider) may be called from different portals (WSRP consumers).
  • Access to the portal user profile
In JSR 168, a portlet can define in the deployment descriptor which user profile information it wants to access. The specification proposes to use a list of standard P3P attributes, however the portlet is free to request any additional user information that is not covered by this attribute list. At deployment time the portal can map the requested user profile attributes to the supported profile attributes or the portal can ignore the requested attributes. At runtime the portlet can use the USER_INFO constant of the PortletRequest to determine which of the requested user profile attributes are available. See User information for a list of attributes supported by WebSphere Portal.
  • Request and response properties
The portlet and portlet container can exchange vendor-specific information using request and response properties. These properties are available in the action request and response and the render request and response. Properties are propagated for includes, but not between the action and render phase. When including a servlet or JSP, the properties are mapped to headers in the servlet API. WebSphere Portal does not support any vendor-specific request or response properties.
  • Web application session scope
JSR 168 API supports the Web application session scope, in which every component of the Web application can share information through the APPLICATION_SCOPE field of the portlet session. This can be used to share transient information between different components of the same Web application, for example, between portlets or between a portlet and a servlet.
  • Reuse of the HttpSession listeners
As JSR 168 reuses the HttpSession, it also allows reusing all the session and attribute listeners that the servlet 2.3 specification defines. JSR 168 provides a PortletSessionUtil class for decoding the attributes of the HttpSession, as these are namespaced in the private portlet session case.
  • Resource bundles
Portlets can define a resource bundle in the deployment descriptor that can be accessed at runtime using PortletConfig.getResourceBundle(). This provides localizations of resources, such as the portlet title, search keywords, or preference names and descriptions. At deployment time, all settings in the portlet descriptor that are intended to be viewed or changed by the administrator (for example, portlet description, init parameters, or display name) can be localized by setting the xml:lang attribute on the associated tag (like the servlet 2.4 deployment descriptor). JSR 168 also recommends a notation for localizing the preference attribute display names, values, and descriptions.
  • Multiple response content types
For each response, portlets can retrieve a list of supported content types using the PortletRequest.getResponseContentTypes() method. This allows portals to indicate to portlets that they have transcoding capabilities.
Portlets receive only content types that they have defined in the <supports> section of the deployment descriptor. If the portlet declares support for content types using wildcards (for example, "text/*" or "*/*") in the deployment descriptor, the portlet container may also set these content types as response content type. Therefore portlets specifying wildcard content types in the deployment should handle wildcard content types as response content types accordingly.
  • Redirect in action
During the action phase, JSR 168 API enables portlets to redirect requests to other Web resources. This allows portlets to process the request from different resources (for example, an accounting servlet) in response to an action.
  • Preference validator
Portlets can provide a class that validates the set of preference values in the PortletPreferences object. The class is defined in the portlet.xml. The preference validator can incorporate logic to check cross-dependencies between different preference properties. The portlet container always calls the validator before storing a preference set to ensure that only consistent preference sets are stored.

Concepts unique to the IBM portlet API

  • Portlet events
The IBM Portlet API has the concepts of events. This event concept is based on the JetSpeed event model, which is similar to the Java event model. The IBM Portlet API provides the following events:
o    ActionEvent
o    MessageEvent
o    PortletApplicationSettingsAttributeEvent
o    PortletSettingsAttributeEvent
o    WindowEvent
  • Additional listeners
The listener concept of the IBM Portlet API allows the portlet to get notifications not only for events as described in the section above, but also for events related to the session lifecycle, event phase lifecycle or render phase lifecycle. The IBM Portlet API provides the following listeners to implement this functionality:
o    PortletPageListener
o    PortletSessionListener
o    EventPhaseListener
  • Portlet menus
The portlet menu service allows the portlet to contribute content to the portal navigation menu, providing users easier navigation through portal pages.
  • Invalidation-based caching
Portlet can actively invalidate the cache using the invalidate method on the portlet request as result of an action. This allows for more fine-grained cache control as the portlet can determine, as a result of this action, whether to invalidate the cache content for only the current portlet mode and markup or for all of the portlet's modes and markups. In JSR 168, an action invalidates all cached markup.

Limitations

The JSR 168 portlet container for WebSphere Portal has the following limitations:
RenderResponse.setTitle(java.lang.String title)
This method is not supported by WebSphere Portal.
Portlet URL security
The setsecure() method of the PortletURL interface is not supported. The portlet URL will always be the same security level of the current request. Likewise, the secure attribute of the <portlet:actionURL/> and <portlet:renderURL/> tags is not supported. See PLT.7.1.2 Portlet URL security in the specification for more information.
Programmatic security
The isUserInRole() method of the portlet request is not supported and always returns false. Any <security-role-ref/> elements in the portlet deployment descriptor are ignored.
The getUserPrincipal() method of the portlet request always returns null if application server security is not enabled. The getRemoteUser() method of the portlet request always returns a unique value for each user, even with security disabled, so that it can be used for personalization purposes, such as storing user-specific preferences. Therefore, you can always use the code fragment request.getRemoteUser() != null to check if a user has logged in. The return value with disabled security might not be a human-readable string and will be different from the value returned when security is enabled.
See PLT.20.3 Programmatic Security in the specification for more information.
Specifying security constraints
The <security-constraint/> element in the portlet deployment descriptor is not supported. See PLT.20.3 Specifying Security Constraints in the specification for more information.
User information
The following attributes are supported in the portlet container for WebSphere Portal. The second column shows the corresponding attribute name in Member Manager (wmmAttributeName).
User attribute name
Member Manager equivalent
user.gender
ibm-gender
user.employer
o
user.department
ou
user.jobtitle
ibm-jobTitle
user.name.prefix
ibm-personalTitle
user.name.given
givenName
user.name.family
sn
user.name.middle
ibm-middleName
user.home-info.telecom.telephone.number
homePhone
user.home-info.online.email
ibm-otherEmail
user.business-info.postal.street
street
user.business-info.postal.stateprov
stateOrProvinceName
user.business-info.postal.postalcode
postalCode
user.business-info.postal.country
countryName
user.business-info.telecom.telephone.number
telephoneNumber
user.business-info.telecom.fax.number
facsimileTelephoneNumber
user.business-info.telecom.mobile.number
mobile
user.business-info.telecom.pager.number
pager
user.business-info.telecom.online.email
ibm-primaryEmail
Prior to V5.1.0.3, all other user attributes not listed here are not supported. Starting with V5.1.0.3, the portlet container also supports arbitrary user attributes. To specify arbitrary user attributes, the portlet needs to specify the Member Manager attribute name in the portlet.xml deployment descriptor under the <user-attribute/> element and can obtain the attribute value by inspecting the USER_INFO map in the request.
See PLT.17 User Information in the specification for more information about user attributes for standard portlets.

This section gives a high level comparison between the new JSR 168 Portlet API and the IBM Portlet API. First, it covers the concepts that are similar; then, it explains some of the differences between the two.
The following concepts are very similar in JSR 168 and the IBM Portlet API.
Feature
Similarities
Differences
Portlet modes
Both support the basic portlet modes: Edit, Help, and View.
The config mode is optional in the JSR 168. The other optional JSR 168 modes (About, Edit_defaults, Preview, Print) are not supported by the IBM Portlet API.
Window states
These window states are supported: Maximized, Normal, and Minimized.
The Solo window state is only supported by the IBM Portlet API.
Portlet lifecycle
The lifecycle life cycle is the same: init, process requests, destroy.
none
Request processing
Request processing is divided into an action phase for processing user actions and a render phase for producing the markup.
none
URL encoding
Both support creating URLs pointing to the portlet or to a resource.
none
Include servlets/JSPs
Servlets and JSPs can be included in the portlet.
none
Portlet session
Portlets can store transient information that should span requests in a session.
none
Portlet application packaging
Both package portlet applications as WAR files with an additional deployment descriptor called portlet.xml.
The portlet.xml format differs.
Expiration-based caching
The portlet can support expiration based caching.
The APIs use different mechanisms to implement this functionality.
The IBM Portlet API uses a polling mechanism where the portal queries the portlet for how long the markup will be valid, whereas in the JSR 168 the portlet can attach an expiration time to each created markup. Sharing the cache entry across users is only possible in the IBM Portlet API.
The JSR 168 and the IBM Portlet API differ in the following ways.
Feature
IBM Portlet API
JSR 168
Portlet application entities
Lets you define an abstract portlet application and different instance of this portlet application as concrete portlet applications via the deployment descriptor. This allows reusing settings of the abstract portlet application and only overwriting the parts that are unique for each concrete portlet application.
The deployment descriptor follows the web.xml deployment descriptor and defines one portlet application and the portlet definitions for this application.
Portlet entity
There is one portlet object instance per portlet configuration in the Web deployment descriptor. There may be many PortletSettings objects parameterizing the same portlet object according to the Flyweight pattern, provided on a per-request basis. Changes in the PortletSettings apply to all portlet instances of this concrete portlet. The user can also have personal views of concrete portlets that are rendered using the PortletData for customization of the output.
PortletSettings and PortletData are merged into one object called PortletPreferences.
Request/Response objects
The request/response object that the portlet receives in the render call is the same as the one received in the action call.
In the JSR 168 these are two different objects.
These items are only available in the JSR 168.
Feature
Description
Render parameters
Render parameters allow the portlet to store its navigational state.
Render parameters stay the same for subsequent render requests and only change when the portlet receives a new action. This enables bookmarkability and solves the browser back button problem.
Global HttpSession scope
Portlets can store data not only with the visibility of the portlet, but also with the visibility of the whole Web application.
Redirect
Portlets can redirect to other Web resources in the action phase.
The following concepts are only available in the IBM Portlet API.
Feature
Description
Eventing
Events can be sent between portlets.
Additional lifecycle listeners
Lifecycle listeners besides action and render, (such as begin page) are not available in the first version of the JSR 168.
Portlet menus
Lets the portlet contribute content to a menu bar to facilitate navigation through portal pages.
Invalidation based caching
Lets the portlet explicitly invalidate cached content.


Developing a "Hello World" Portlet

Now it is time to develop a sample HelloWorld portlet.
  1. Create a HelloWorld web project. Similar to a normal servlet project, it should have a /WEB-INF/web.xmlfile that will be the deployment descriptor of the project.
  2. Add portlet-api-1.0.jar file to your build path. This .jar is part of the Pluto distribution.
  3. Inside of your Source folder, create a HelloWorld.java file, like this:
public class HelloWorld extends GenericPortlet{
  protected void doView(RenderRequest request,
  RenderResponse response) throws
  PortletException, IOException {
        response.setContentType("text/html");
        response.getWriter().println("Hello Portlet");
        }
}
Every portlet should implement the Portlet interface. This interface defines the life cycle methods for a portlet. Since you don't want to override all of those methods, we will extend the GenericPortlet class, which is an adapter class implementing the Portlet interface. It provides default implementations of all life cycle methods, so we only have to implement necessary methods.
The only thing that we want to do in our HelloWorld portlet is to display "Hello Portlet." So we will override the doView() method of the GenericPortlet class. This method takes a PortletRequest and a PortletResponse as arguments. Call response.setContentType() first thing in the doView() method to inform the portlet container about what content type the portlet is going to generate--failure to do so will result in an IllegalStateException. Once the content type is set, you can get a PrintWriter from the response object and start writing into it.
  1. Every portlet application should have a portlet.xml file in the /WEB-INF folder, which is the deployment descriptor for a portlet application. Create a portlet.xml file, like this:
<portlet>
  <description>HelloWorldDescription
        </description>
 
    <portlet-name>HelloWorld
        </portlet-name>
    <display-name>Hello World
        </display-name>
 
    <portlet-class>com.test.HelloWorld
        </portlet-class>
    <expiration-cache>-1
        </expiration-cache>
 
        <supports>
          <mime-type>text/html</mime-type>
          <portlet-mode>VIEW
          </portlet-mode>
        </supports>
 
    <supported-locale>en
        </supported-locale>
 
        <portlet-info>
          <title>Hello World</title>
          <short-title>Hello World
          </short-title>
          <keywords>Hello,pluto</keywords>
 
      </portlet-info>
</portlet>
The <portlet-name> element declares the name of the portlet. The <portlet-class> element specifies the fully qualified class name of portlet. The <expiration-cache> element specifies the time in seconds after which content is considered to be stale. This is a little bit more complicated than that: if you perform some action on the portlet, then new content will be generated, irrespective of cache time.
The <supports> element specifies which modes are supported for a given <mime-type>. In our example, we are saying that HelloWorld can only generate content of the text/html content type, and for the text/html content type, only the view mode is supported. If you decide to add support for other content types, then you should add new <support> elements and specify what modes are supported for that MIME type. It is very common for a portlet to have VIEW, EDIT, and HELP modes for text/html, and only VIEW mode for the WML MIME type.
You can also specify what locales the portlet supports by using the <supported-locale> element. The <title> element is used to specify a title for the portlet. If you want an internationalized title, then you can specify the name of the resources (i.e., a .properties) file using the <resource-bundle> element. In that case, the container will choose a title from the appropriate .properties file, based on the user's locale.
  1. Every portlet application is a web application, so it requires a web.xml file in addition to portlet.xml.
<web-app>
  <display-name>Hello World Portlet
  </display-name>
  <welcome-file-list
    <welcome-file>index.jsp
        </welcome-file>
 
  </welcome-file-list>
</web-app>
  1. The next step is compiling this content and packaging it into a .war file. You can do that yourself or download the sample code (see the "Resources" section) that has a build.xml that your can use for creating the .war file.

Adding Support for Edit Mode

As discussed , the portlet specification defines three modes:


1.    VIEW: For activities related to the expected functionality of your portlet.
2.    EDIT: For configuration activities.
3.    HELP: For displaying help.
We will take the HelloWorld.zip sample portlet developed in the first installment and modify it to enable the EDIT mode.
1.    Change your HelloWorld.java file like this:
2.  public class HelloWorld extends GenericPortlet{
3.  protected void doView(RenderRequest request,
4.  RenderResponse response) 
5.  throws PortletException, IOException{
6.    response.setContentType("text/html"); 
7.    response.getWriter().println("Hello World Portlet");
8.   }
9.  protected void doEdit(RenderRequest request, 
10.RenderResponse response) 
11.throws PortletException, IOException {
12.  response.setContentType("text/html");
13.  response.getWriter().println(
14.    "Hello World Portlet- Edit Mode");
15. }
}
In order to enable EDIT mode, we have to override the doEdit() method in HelloWorld.java. The doEdit() method gets called when the portlet is opened in EDIT mode, and supposed to generate markup. Inside of the doEdit() method, we first want to declare that the content type is text/html, and then write a one-line message informing user that he or she is accessing the HelloWorld Portlet in EDIT mode.
16.  Change the portlet.xml file like this.
17.<supports>
18.  <mime-type>text/html</mime-type>
19.  <portlet-mode>VIEW</portlet-mode>
20.  <portlet-mode>EDIT</portlet-mode>
</supports>
This change in portlet.xml will inform the portlet container that the HelloWorld portlet supports EDIT mode in addition to VIEW mode. Adding the <portlet-mode>EDIT<portlet-mode> subelement to the <supports> element is what accomplishes this. The <supports> element tells the container two things: the HelloWorld portlet can generate text/html-type content, and that for text/html content, it supports VIEW and EDIT modes.
In addition to the pre-defined VIEW, EDIT, and HELP modes, the portlet specification allows portlets to take advantage of vendor-specific portlet modes. For example, IBM's WebSphere portal server has the concept of a CONFIG mode, which allows an administrator to configure the portlet. To use this, you can declare a custom CONFIG mode in your portlet.xml and add the corresponding doConfig() method in your HelloWorld.java method (actually it requires a few more steps, described in the portlet specification). As a result, when the HelloWorld portlet is deployed on IBM's WebSphere Portal Server, it will display an icon for CONFIG mode in addition to the other modes. But if this portlet is deployed on some other portlet container, the user won't be able to enter CONFIG mode.

Using JSP to Display Help

One of the problems with the HelloWorld sample portlet is that we are generating markup inside of Java code, specifically in the HelloWorld.java class. This approach is not acceptable for developing an industrial-strength portlet. In that case, you may want to keep your business logic inside of the Java code and pass control to a JSP page for markup generation. Portlet Specification 1.0 says that portlet container should be J2EE-1.3-compliant. A portlet can pass control to either a servlet or a JSP for markup generation. Portlets use a concept of a RequestDispatcher, similar to the class of the same name in the servlet API. Lots of work is going on to port popular servlet-based MVC frameworks to the portlet environment, such as the Struts, JSF, and Spring frameworks.
Now we will change our HelloWorld portlet to do two things: enable HELP mode, and use the Help.jsp page for generating markup. Follow these steps.
1.    Create \html\Hello.jsp under the Web Content folder. Add only one line in this file, saying "Help.jsp - HelloWorld Portlet in Help mode."
2.    Change HelloWorld.java to add the doHelp() method, like this:
3.  protected void doHelp(RenderRequest request, 
4.  RenderResponse response) 
5.  throws PortletException, IOException {
6.   PortletRequestDispatcher dispatcher = 
7.      getPortletContext().getRequestDispatcher
8.          ("/html/helloworld.jsp");
9.   dispatcher.include(request, response);
}
In this method, you first get the handle to PortletRequestDispatcher by passing it the path of JSP that you want to use for markup generation. Next, you pass control to that JSP by calling the include() method of the PortletRequestDispatcher.
Portlets generate markup fragments that are aggregated in a portal page document. Because of this, there are some rules and limitations in the markup elements generated by portlets. Portlets should conform to these rules and limitations when generating content.
1.    Portlets should not use tags that impact content generated by other portlets or that may even break the entire portal page. Inclusion of such a tag invalidates the whole markup fragment.
2.    Portlets generating HTML fragments must not use the following tags: base, body, iframe, frame, frameset, head, html, or title.
3.    Portlets generating XHTML and XHTML-Basic fragments must not use the following tags: base, body, iframe, head, html, or title.

Portlet Request Processing

Now it's time to talk about a most interesting aspect of portlet technology: how portlets process a request. We will take one backward step first. In the previous article's How a Portal Page is Created section, we said that most portals are implemented as web applications, and are deployed in an application server. In the case of Pluto, the org.apache.pluto.portalImpl.Servlet is mapped to receive all requests. So the first point of contact is a servlet that gets the browser request and generates markup.



Play little with your HelloWorld application a little bit, and you will note that whenever you are interacting with one of the portlets, the whole page gets refreshed. In other words, if you perform some action on Deploy War Admin Portlet, the complete page will get refreshed instead of only that portlet.
Let's look at an example of what happens when you're interacting with a portal. We will assume that you have two portlets, called A and B, on one page. Portlet A can get a request in either of two cases.
1.    The user clicked a link or submitted a form in Portlet A. In this case, Portlet A should do something, like execute some business logic and generate new markup. This is called action processing because the user is performing some action on Portlet A.
2.    The user is performing some action on Portlet B, and as a result, the complete page needs to be regenerated. Please note that when the user performs this action, the browser won't only update the content of Portlet B; instead, it will ask the portal server to regenerate the complete page. In this case, Portlet A should not execute any business logic; instead, it should regenerate markup. This is called the render phase.
Figure 2 shows how a request is handled in the portal server.
Portal Request Handling
Figure 2. Portal request handling
When the user clicks a link on Portlet A, the browser will submit the request to the portlet container. The portlet container will be notified that some action was performed on Portlet A, and will call the processAction() method of Portlet A. This is called the action processing phase. Once action processing is complete, the container will start the render phase. In this phase, the container figures out how many portlets are on the requested page. In this case, there are two portlets, A and B, so it will call the render() method of both these portlets in different threads. Once control returns back from both these methods, it will take the content/fragment generated by them and aggregate it to build the complete page. So when the user performs action on one of the portlets, the page gets the processAction method call and all portlets on the page get a render method call.
What happens if user clicks the Refresh button? Or what if the user visits or returns to the page where both of these portlets are placed? The container has to generate markup for the page, but no action is performed on any of the portlets. In this case, when the container gets the request, it will skip the action phase and in the render phase it will call the render() method of all portlets on the page.
The portlet interface has two different methods to represent two different phases of request processing.
1.    processAction(ActionRequest actionRequest, ActionResponse actionResponse): The portlet container will call this method when some action is performed on a portlet. It will pass information submitted by the user, such as values entered in a form, in an ActionRequest object. You can use the ActionResponse to redirect the user to a new page.
2.    render(RenderRequest renderRequest, RenderResponse renderResponse): This method is similar to the service() method in the Servlet API. It is called in the render phase, but you should not override it directly. Instead, you override one of the mode-specific methods, such as doView(), doHelp(), or doEdit(). The render() method will determine the mode requested by the user and call the appropriate doMode() method. The portlet container will pass a RenderRequest and RenderResponse to this method. The developer can write markup via the object returned by renderResponse.getWriter(). But RenderRequest does not directly get HTML form values submitted by the user--instead, it has go through PortletSession. This is getting complicated, so we will handle it separately in the next section.

Greet User with Personalized Message

In last section we talked about how the portlet container processes requests. In this section, we will clarify portlet request processing concepts by changing the HelloWorld portlet to handle the processAction() method call. What we will do is ask user for his or her name in EDIT mode, and then use that name to greet the user in VIEW mode. Follow these steps:


1.    Change the HelloWorld.java file, like this.
2.  protected void doView(RenderRequest renderRequest, 
3.  RenderResponse renderResponse)
4.  throws PortletException, IOException {
5.  renderResponse.setContentType("text/html");
6.    String userName = (String) renderRequest.
7.      getPortletSession().getAttribute("username");
8.    if (userName != null)
9.      renderResponse.getWriter().println("Hello " 
10.      + userName);
11.  else
12.    renderResponse.getWriter().println("Hello how 
13.     are you doing. Go to edit mode and set name");
14.}
15. 
16.protected void doEdit(RenderRequest renderRequest, 
17.RenderResponse renderResponse)
18.throws PortletException, IOException {
19.  PortletRequestDispatcher dispatcher = 
20.  getPortletContext().getRequestDispatcher(
21.    "/html/username.jsp");
22.  dispatcher.include(renderRequest, renderResponse);
23.}
24. 
25.public void processAction(ActionRequest 
26.actionRequest, ActionResponse actionResponse) 
27.throws PortletException, IOException {
28.  String userName =
29.    actionRequest.getParameter ("username");
30.  actionRequest.getPortletSession().setAttribute
31.    ("username", userName);
32.  actionResponse.setPortletMode(PortletMode.VIEW);
}
As you can see, we have to make lots of changes in HelloWorld.java in order to greet the user with his or her name. Let's take a look at each of these changes.
o    doEdit(): Now we pass control to username.jsp to generate a form that will ask the user for his or her name.
o    processAction(): This method gets called only when user goes to EDIT mode and submits a form. Inside of this method, the first thing we do is to call actionRequest.getParameter() to find the value of the userName input submitted by the user.
We then set this value as an attribute in the portletSession object. Please note that the ActionRequest object is different than RenderRequest, so you can set an attribute in ActionRequest and expect it to be available in RenderRequest. Also the portlet container will create only one instance of Portlet to serve multiple requests (similar to Servlet), so you cannot pass a value from the action phase to the render phase as an instance or static variable of the Portlet class. The last line is actionResponse.setPortletMode(PortletMode.VIEW). This is called because once the user submits a name, we want to change the mode back to VIEW mode. This way, when the render() method is called, it will route the user request to the doView() method instead of the doEdit() method.
o    doView(): In this method, we will check if the userName attribute is already set in the PortletSession object. If so, we use the value of that attribute to greet the user; if it is not set, then we display a message informing the user how to set userName.
33.  Create /html/username.jsp inside of the Web Content folder. This JSP will be used to solicit input from the user in EDIT mode.
34.<%@ page language="java"%>
35.<%@ taglib uri="http://java.sun.com/portlet" 
36.prefix="portlet"%>
37.<portlet:defineObjects/>
38.<form action='<portlet:actionURL />'>
39.<table>
40.<tr>
41.        <td>User Name</td>
42.        <td>
43.                <input type="text" name="username"/>
44.        </td>
45.</tr>
46.<tr>
47.        <td>
48.                <input type="submit" label="Save"/>
49.        </td>
50.</tr>
51.</table>
</form>
This JSP is like any typical JSP with the difference of the <portlet:defineObjects> tag. The portlet specification defines the portlet tag library with the aim of solving common problems faced by portlet developers. The portlet tag library is very important concept, and we'll revisit it shortly.
Build your application and deploy it on Pluto. When you go to VIEW mode, it will ask you to go to EDIT mode and enter a user name. Enter userName and click Submit; this should take you back to VIEW mode, which will display a message saying "Hello your-name." You know, one of the problems of being a UI developer is that you don't feel like you're learning something unless you see some change in the UI.

The Portlet Tag Library

The portlet specification mandates that every portlet container should provide an implementation of the portlet tag library, portlet.tld. The portlet tag library enables JSPs that are included by portlets to have direct access to portlet-specific elements such as RenderRequest and RenderResponse. It also provides JSPs with access to portlet functionality such as the creation of portlet URLs. JSP pages using the tag library must declare this in a taglib declarative statement like this (using the suggested prefix value):
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
Available tags include the following:
1.    <portlet:defineObjects/>: This tag must appear to define the following variables in the JSP page: renderRequest, renderResponse, and portletConfig. A JSP using the defineObjects tag may use these variables from scriptlets throughout the page.
2.    <portlet:actionURL/>: The portlet actionURL tag creates a URL that must point to the current portlet and must trigger an action request with the supplied parameter. The parameters may be added to the URL by including the param tag between the actionURL start and end tags:
3.  <portlet:actionURL windowState="maximized" portletMode="edit">
4.          <portlet:param name="action" value="editStocks">
</portlet:actionURL>
The example creates a URL that brings the portlet into EDIT mode and MAXIMIZED windowState to edit the stock quote list.
5.    <portlet:renderURL/>: This tag creates a URL that must point to the current portlet and must trigger a render request with the supplied parameter. The renderURL tag also takes parameters using the param tag, and allows the attributes forwindowState and portletMode.
6.    <portlet:namespace/>: This tag produces a unique value for the current portlet. Namespacing ensures that the given name is uniquely associated with this portlet and avoids name conflicts with other elements on the portal page or with other portlets on the page.
<A HREF="javascript:<portlet:namespace/>test()">Encoded name</a>
let us talk practically...



Portlet A is developed by developer A and portlet B is developed by developer B and both have kept their portlet on the same page.

Both portlets has a submit button.



Now, there would always be higher possibility that both the portles have the same java script function name for submit button, and when you hit submit button of portlet A, which javascript submit function will be called? you can never say, because both the portles have exactly same function name.



To overcome this issue, JSR 168 introduced portlet namespace which differentiate two javascript functions with the same name.



By applying <portlet:namespace/> with a java script function, it generates a unique alpha numeric string for each portlet and append it to function name.



// namespaced javascript function

function submit<portlet:namespace/>(){

// function code

}

this will internally converted into

function submitns_7_CGAH47L00GSJC0IOF0L4TT30G7_(){ 

// function code 

}

and makes it unique javascript function



// call to function

<a href="onClick='submit<portlet:namespace/>()'>Submit</a>



As per JSR168 portlet best practice, one should always namepsace

javascript functions.

example:- function submit<portlet:namespace/>(){ }

Form Name.

example :- <form name="formOne<portlet:namespace/>" action="<portlet:actionURL/>">

javascript global variables.



Important, you can also get portlet name space from RenderRequest

String portletNameSpace = renderResponse.getNamespace();
 
 

Portlet Preferences

One of the requirement for portlets is that the user should be able to customize their view or the behavior of the portlet. The portlet specification provides you with a PortletPreferences object that allows you to store configuration data as name-value pairs. The most valuable part is that configuration is persisted, so it will be available across server restarts. You don't have to worry about how the portlet container is storing or retrieving configuration data. Another important point in the specification is that preferences attributes are user-specific. This means that you cannot design a portlet where changes made by an administrator are stored in PortletPreferences object and made available to all users (actually, some portlet vendors provide way to achieve this in a container-specific way).
We will make one more change to our HelloWorld portlet so that it remembers the userName even after a restart. Change HelloWorld.java like this:
protected void doView(RenderRequest request, 
  RenderResponse response)
  throws PortletException, IOException {
    response.setContentType("text/html");
    String userName =
      (String)request.getPreferences()
      .getValue("userName",null);
    if (userName != null)
          response.getWriter().println("Hello " + userName);
    else
      response.getWriter().println
        ("Go to edit mode and set name");
}
 
public void processAction(
  ActionRequest actionRequest, 
  ActionResponse actionResponse) 
  throws PortletException, IOException {
    String userName =
      actionRequest.getParameter ("userName");
    PortletPreferences pref =
      actionRequest.getPreferences();
    pref.setValue("userName",userName);
    pref.store();
    actionResponse.setPortletMode(PortletMode.VIEW);
}
We are not using the PortletSession object to store the userName attribute anymore. Inside processAction(), we first get the value of the userName attribute submitted by user, and set it in the PortletPreferences object by calling the method pref.setValue("userName",userName). The next step is to call the store() method on PortletPreferences, which saves the changes made in PortletPreferences to the persistence store.
There are a couple of important points to remember. First, you can modify PortletPreferences only inside of the processAction() method. Trying to call it during render() will result in an IllegalStateException. Secondly, if you don't call the store() method after changing PortletPreferences and before exiting the processAction(), then those changes will be discarded. The PortletPreferences interface also defines a reset() method, which can be used to reset values of preferences attributes to default values.

Caching

The portlet specification defines an expiration-based caching mechanism. This caching mechanism is per-portlet and per-client, with a restriction that cached content must not be shared across different user clients displaying the same portlet.
The way it works is that a portlet that wants its content to be cached using the content cache must define the duration of the expiration cache in a deployment descriptor, like this:
<portlet>
  <expiration-cache>300</expiration-cache>
</portlet>
Now suppose Portlet A has defined that it wants it content to be cached for 300 seconds and it is placed on a page along with Portlet B. If the user performs some action on Portlet B, the portlet container can choose to use cached content generated by Portlet A instead of calling its render() method again. But if the user performs some action on Portlet A, the container should invalidate the cached content of Portlet A and call its render() method once again.
Please note that it is not necessary for a portlet container to implement caching, and it can choose to disable caching any time it wants. But if the container does implement this feature, it helps improve portlet response time and reduce load on the server.

  • SSO Implementation : Through SPENGO
  • By default, WebSphere Portal Server automatically installs and stores its predefined data in the IBM Cloudscape Database


Explain Portal architecture.

The core implementation of the portal is UI, hosted by a Portal server. The HTTP requests, HTML responses, and returning appropriate portal pages are handled by the Portal UI. Enterprise Web application also can be handled by the Portal Server.
The portal architecture has the following:
Automaton Server: This server performs the management of job scheduling and implementation of a portal. It accesses all remote crawlers and profile services retrieved and stored from a remote database.
Image Server: This server hosts images and other web page content used by web services and a portal. With this configuration, large static files are to be sent directly to the browser without portal server impacts.
Search Server: This server indexes and searches all the information, applications, communities, documents, web sites through portal.
Collaboration Server: Web content publication and management for portals and web applications are supported by this server. Its functionality can be accessed by a remote web services through Enterprise Web Development kit.
Content Server: Publication and management of web content for portals and web applications along with form based publishing, branding, templates, content expiration is allowed by this server.
Authentication Server: This server handles the portal authentication for users and remote services can be accessed through EDK.
Remote Servers: Web services written using the EDK are hosted by remote servers. The servers can be in different countries, on different platforms and domains. 

PortletSession interface?

User identification across many requests and transient information storage about the user is processed by PortletSession interace. One PortletSession is created per portlet application per client.
The PortletSession interface provides a way to identify a user across more than one request and to store transient information about that user.
The storing of information is defined in two scopes- APPLICATION_SCOPE and PORTLET_SCOPE.
APPLICATION_SCOPE: All the objects in the session are available to all portlets,servlets, JSPs of the same portlet application, by using APPLICATION_SCOPE.
PORTLET_SCOPE: All the objects in the session are available to the portlet during the requests for the same portlet window. The attributes persisted in the PORTLET_SCOPE are not protected from other web components

PortletContext interface?

The portlet view of the portlet container is defined by PortletContext. It allows the availability of resources to the portlet. Using this context, the portlet log can be accessed and URL references to resources can be obtained. There is always only one context per portlet application per JVM.
Function-based portals
Horizontal Portals:
These are the portals are of type general interest. Yahoo!,Lycos,AOL,Freeserve,Sympatico are examples of horizontal portals.
Vertical Portals
They provide a gateway to the information pertaining to a specific industry such as insurance, banking, finance, automobile, telecom etc.
User-Based Portals
B2B Portals
The enterprises extend to suppliers and partners by using B2B portals.
B2C Portals
The enterprises extend to customers for ordering, billing, services by using B2C portals.
B2E Portals
The enterprise knowledge base integration and related applications into user customizable environment is done with B2E portals. This environment is like one stop shop
Copy Portlet
Copy portlet, one of the feature of WebSphere Portal, that i have implemented in my projects.It is a very good feature, once you use it you will realise it's power.
I am sharing my experience, when i suggested to use Copy Portlet concept in my projects and it saved major time frame.
For one of my project of US client for their WebSphere Portal implementation, there was a requirement in which they have two portal pages and both the page having the same portlet.
Basically, they wanted to have same portlet on both the pages but displaying data from different database schema.
How would you achieve this? just think about it for few mins before reading down....
The solution i suggested them to create Copy of the portlet and put it on another page. Provide schema name as parameter to copy portlet.
As as result, the rendering portlet will fetch the data from appropriate database schema, based on the parameter retrieved from copy portlet instance.
My another experience was with one of NewZeland based client.
Here, they have same page in the Top Navigation and in Left navigation, both top and left nav pages have the same portlet.
They wanted to have functionality like, landing screen of the portlet should be different as a result of top nav page click and left nav page click.
To achieve this, they started thinking to create two different portlet application which are going to be placed on top nav page and left nav page respectively.
In between, i suggested them to create Copy of existing Portlet and put on left nav page and provide parameter to copy portlet and based on the parameter value, portlet will render appropriate screen.

 

 

 

How to Move a portal page on WPS?

Moving a portal page involves, changing of parent page/label.

This kind of scenario could arise when you have portlets added on portal pages and later in futureyou are required to move page from one place to another.Also this page move should not disturb portlets on page being moved.

Here i am explaining with a sample page move...

Considering, we have Page A and Page B as two parent page/label.
Page P1 and Page P2 are under Page A and
Page P3 and Page P4 are under Page B.
Page A ==== Page B
Page P1 -------- Page P3
Page P2 ------- Page P4

Scenario is like, We want to move Page P4 from Page B to Page A and and this moving of pages should not disturb portlets added on page P4.

Here is how you can perform page Move...

1) Login to portal as admin
2) Go to Administration
3) Navigate to Portal User Interface --> Manage pages
4) Find Page P4
5) Click on Mark icon adjacent to Page p4.
6) You can see a message saying, "Page P4 is ready to be moved." on top of Manage Pages portlet.
7) Navigate to the page where you want page P4 to be moved. In our case, it is Page A.
8) Navigate to Page A.
Note:- You can now see Move button along with New Page, New label, New URL.
9) Click on Move button and you are done with moving page P4 under Page A.

As as result, you can see that Page p4 is moved from PageB and is now available under PageA
What is IBM HeapAnalyzer?
IBM HeapAnalyzer implements a new technology that allows the finding of a possible Java heap leak area through its heuristic search engine and analysis of the Java™ heap dump in Java applications.

How does IBM HeapAnalyzer work?
IBM HeapAnalyzer analyzes Java heap dumps by parsing the Java heap dump, creating directional graphs, transforming them into directional trees, and executing the heuristic search engine. The following are examples of features:
  • List of objects/classes/arrays by size
  • List of objects/classes/arrays by size of child
  • List of objects/classes/arrays by number of child
  • List of objects/classes/arrays by frequency
  • List of objects/classes/arrays by alphabetical order
  • List of available heap spaces by size
  • Available heap space distribution chart
  • Tree view of Java heap dump
  • Locations of possible Java heap leak areas
  • Loading/Saving processed Java heap dumps.


What can I find a Java heap leak with in HeapAnalyzer?
The following is a snapshot of IBM HeapAnalyzer. One of the possible memory leak areas is highlighted in the tree view. There are 192 entries of java.util.Hashtable$Entry (44% of total Java heap, Heap size is 258,494,664 bytes, TotalSize of java.util.Hashtable$Entry is 114,724,208 bytes) referenced in the org.apache.xml.utils.XMLReaderManager object which has a memory leak (reported in XSLT4J Java 2.6.2).

 

Heapdumps

The JVM checks each of the following locations for existence and write-permission, then stores the Heapdump in the first one that is available:
  1. The location that is specified by the IBM_HEAPDUMPDIR environment variable, if set.
  2. The current working directory of the JVM processes:
·         For WebSphere Portal running on WebSphere Application Server 6.0, this is directory <wp_profile_root> (for example, /opt/IBM/WebSphere/AppServer/profiles/wp_profile).
·         For WebSphere Portal running on WebSphere Application Server 5.1, this is directory <was_root> (for example, /opt/IBM/WebSphere/AppServer).
                        The location that is specified by the TMPDIR environment variable, if set.
                        The /tmp directory (X:\tmp for Windows, where X is the current working drive).


Note that enough free disk space (possibly up to 1 GB) must be available for the Heapdump file to be written correctly.


(Web Services for Remote Portlets) Dynamic plug-ins for portal pages. Officially ratified as an OASIS standard in September 2003, WSRP defines how to plug remote web services into the pages of online portals and other user-facing applications. This allows portal or application owners to easily embed a web service from a third party into a section of a portal page (a 'portlet'). The portlet then displays interactive content and services that are dynamically updated from the provider's own servers. Formerly known as Web Services for Remote Portals, WSRP is closely allied with WSIA (Web Services Interactive Applications). A separate Java standard for portlets is known as JSR 168.

Introduction to Web Services for Remote Portlets
Summary:  Get an introduction to Web Services for Remote Portlets (WSRP), a specification which defines how to leverage SOAP-based Web services that generate mark-up fragments within a portal application. By defining a set of common interfaces, WSRP allows portals to display remotely-running portlets inside their pages without requiring any additional programming by the portal developers. To the end-user, it appears that the portlet is running locally within their portal, but in reality the portlet resides in a remotely-running portlet container, and interaction occurs through the exchange of SOAP messages. Leveraging WSRP within a Service-Oriented Architecture provides a powerful combination whereby presentation-oriented portlet applications can be discovered and reused without engaging in additional development or deployment activities.
A couple of the most important terms in the above definition warrant special attention. First, the services are presentation-oriented which means that they provide a user interface that allows an end-user to interact directly with the service. This is starkly different from a traditional Web service which focuses on processing a request and generating a response at a more programmatic level. Second, the specification defines a common, well-defined interface governing how a portal communicates with the service and collects the mark-up fragments it needs to present a page to the end-user. It is precisely this common interface which allows portal applications to generically consume portlets running in remotely-running containers
If Web services offer a mechanism to create platform-independent services, and JSR-168 defines a standard by which to develop portlets, why do you need WSRP? The answer is simple. While Web services give you the ability to reuse back-end services, WSRP lets you reuse the entire user interface!
For example, you might want to provide end-users of a portal the ability to look-up the price of a stock by entering a ticker symbol. You know that there is likely already a Web service which provides precisely this capability. You could search for stock-quote services in UDDI registries for a Web service that performs this service. Upon finding such a service, you would next need to code a client to bind to and consume the Web service, as well as develop a portlet to allow portal users to interact with the service. Using a Web service toolkit might make developing the Web service client relatively painless; however, developing the user interface might not be such a trivial endeavor. Additionally, you must go through the process of deploying the newly developed portlet and Web services client on your portal server. By the end of the day, you've been forced to develop, compile, and deploy a substantial amount of new code to bring the stock quote service functionality to the end-user. While leveraging a stock quote service developed by a third-party does cut down on development time, the process of developing and deploying the front-end application needed to make the functionality usable by a portal user is tedious and time-consuming.
Building on this same example with WSRP in the mix, you could much more easily integrate a stock quote portlet into your portal. You could browse the UDDI directory for portlets themselves or alternatively provide end-users with the ability to browse a registry of portlets. Once the Stock Quote Portlet has been discovered, the process of adding it to the portal takes just a few clicks of the mouse and you are done. You don't need to perform any custom coding or deployment activities since the portlet is being consumed through WSRP. The end-user doesn't need to understand anything about WSRP or even that their portlet is actually being hosted by a remote producer! The end-user only knows that they have a directory of available portlets from which they can pick and choose. What could be easier?


Before digging in to how WSRP actually works, let's briefly investigate the different moving parts within a WSRP architecture. Figure 3 below illustrates each of the primary actors within a WSRP architecture and the role a portal plays in aggregating the mark-up fragments. Although this diagram shows a portal consuming WSRP portlets from only a single producer, there is no reason why a portal couldn't consume portlets from any number of WSRP producers. The WSRP Specification defines the following actors within WSRP architecture:
  • WSRP producer: This is a Web service that offers one or more portlets and implements a set of WSRP interfaces, thus providing a common set of operations for consumers. Depending on the implementation, a producer could offer just one portlet, or could provide a run-time (or a container) for deploying and managing several portlets. The WSRP producer is a true Web service, complete with a WSDL and a set of endpoints. Every producer in WSRP is described using a standardized WSDL document.
  • WSRP portlet: A WSRP portlet is a pluggable user interface component that lives inside of a WSRP producer and is accessed remotely through the interface defined by that producer. A WSRP portlet is not a Web service in its own right (it cannot be accessed directly, but instead must be accessed through its parent producer).
  • WSRP consumer: This is a Web service client that invokes producer-offered WSRP Web services and provides an environment for users to interact with portlets offered by one or more such producers. The most common example of a WSRP consumer is a portal.
As alluded to previously, WSRP defines a set of common interfaces that all WSRP Producers are required to implement and which WSRP Consumers must use to interact with remotely-running portlets. Standardizing these interfaces allows a portal to interact with remotely-running portlets generically, since it has a well-defined mechanism for communicating with any WSRP-compliant producer. The WSRP Specification requires that every producer implement two required interfaces, while allowing them to optionally implement two others as well:
  • Service Description Interface (required): The Service Description Interface allows a WSRP producer to advertise its capabilities to perspective consumers. A WSRP consumer can use this interface to query a producer to discover what portlets the producer offers, as well as additional metadata about the producer itself. This interface can act as a discovery mechanism to determine the set of offered portlets, but also importantly allows consumers to determine additional information about the producer's technical capabilities. The producer's metadata might include information about whether the producer requires registration or cookie initialization before a consumer can interact with any of the portlets.
  • Mark-up Interface (required): The Markup Interface allows a WSRP consumer to interact with a remotely running portlet on a WSRP producer. For example, a consumer would use this interface to perform some interaction when an end-user submits a form from the portal page. Additionally, a portal might need to simply obtain the latest mark-up based on the current state of the portlet (for example when the user clicks refresh or interaction with another portlet on the same page takes place).
  • Registration Interface (optional): The Registration Interface allows a WSRP producer to require that WSRP consumers perform some sort of registration before they can interact with the service through the Service Description and Mark-up interfaces. Through this mechanism a producer can customize its behavior to a specific type of consumer. For example, a producer might filter the set of offered portlets based on a particular consumer. In addition, the Registration Interface serves as a mechanism to allow the producer and consumer to open a dialogue so that they can exchange information about each others' technical capabilities.
  • Portlet Management Interface (optional): The Portlet Management Interface gives the WSRP consumer access to the life cycle of the remotely-running portlet. A consumer would have the ability to customize a portlet's behavior or even destroy an instance of a remotely-running portlet using this interface.
Listing 1 shows an example WSDL definition of a service which supports both the required and optional interfaces"
                                                 
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:urn="urn:oasis:names:tc:wsrp:v1:bind" 
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  targetNamespace="urn:myproducer:wsdl">
  <wsdl:import namespace="urn:oasis:names:tc:wsrp:v1:bind" 
        location="http://www.oasis-open.org/committees/wsrp/
                                     specifications/version1/wsrp_v1_bindings.wsdl"/>
  <wsdl:service name="WSRPService">
    <wsdl:port name="WSRPBaseService" 
                   binding="urn:WSRP_v1_Markup_Binding_SOAP">
            <soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
                          location="http://myproducer.com:7007/portal/producer"/>
    </wsdl:port>
    <wsdl:port name="WSRPServiceDescriptionService" 
               binding="urn:WSRP_v1_ServiceDescription_Binding_SOAP">
            <soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                          location="http://myproducer.com:7007/portal/producer"/>
    </wsdl:port>
    <wsdl:port name="WSRPRegistrationService" 
               binding="urn:WSRP_v1_Registration_Binding_SOAP">
            <soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                              location="http://myproducer.com:7007/portal/producer"/>
    </wsdl:port>
    <wsdl:port name="WSRPPortletManagementService" 
               binding="urn:WSRP_v1_PortletManagement_Binding_SOAP">
        <soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                              location="http://myproducer.com:7007/portal/producer"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
                                     
                                     


Discover portlets using a UDDI registry
One of the primary benefits of using a portal is that a portal user can customize the set of applications (portlets) that are available to him. The user can create his own pages and add in new portlets as he sees fit. However, to customize the portal in such a manner, he must first be aware of what portlets are available. If there is a central registry (or potentially several registries), portal users can dynamically discover and bind to new portlets, thus creating a work environment tailored to their specific needs.
From the portlet providers' point of view, a centralized registry is equally important since it allows them to publish and describe the portlets which they offer. Providers can provide textual descriptions, categorizations, and other meaningful metadata which richly describe their portlets so that consumers can more effectively discover these services. After all, what is the point of offering portlets to a community if no one knows that they exist?
Universal Description Discovery Interface (UDDI) provides just such a mechanism to bring together WSRP producers who have portlet services to share and WSRP consumers who are seeking to leverage new applications within their work environment. Since UDDI has become the standard for Web services discovery, it is only natural that UDDI also serves as the backbone for portlet discovery. Portlet discovery, however, does throw a few quirks into the mix -- a portlet is not a true Web service after all.
As mentioned above, in the WSRP world there are WSRP producers which are true Web services and WSRP portlets which can only be accessed through the API provided by their producer. While a WSRP portlet can be logically thought of as a service, it is not a true Web service since it does not offer an API by which a consumer could invoke it directly. However, the most common use case when dealing with portlet discovery would involve an end-user looking to find a portlet to add into one of his portal pages. The end-user has no concept of a WSRP producer, nor should he have any reason to understand the underpinnings of WSRP. However, since a portlet can be only be accessed through its producer, both the WSRP portlet and the WSRP producer must be published in the registry.
It should be noted that once a consumer has discovered a portlet service within the registry, the portlet's metadata will contain all of the information necessary for the consumer to directly contact the producer and consume the portlet. Portlet discovery strictly acts as a mechanism to allow producers to describe their portlet services in a central location where potential consumers can discover them.
Figure 4 shows a typical usage scenario, which normally has the following steps:
  1. A provider has developed a set of portlets which have been made available by setting up a WSRP producer and exposing them as WSRP portlets. The provider wants to make these portlets available to the community, so he publishes them to a central UDDI directory. Since UDDI exposes a Web service interface itself, the provider would likely perform this task either through a custom built UI or through one provided by the UDDI Server.
  2. An end-user is looking to add a portlet to his portal. Using the tools provided by his portal (or a custom-written tool specifically for the purpose), he performs a search for portlets. Once the user has found a portlet that he wishes to add to his portal, he easily adds the new portlet application to one of his portal pages. Alternatively, a portal administrator could search the UDDI registry for portlets and make them available to end-users by adding them to the portal's internal registry.
  3. When the user now accesses the page to which he added the new portlet, it now contains the remotely-running portlet. Behind the scenes the portal is making a Web service request to the remote producer, and the producer is returning a mark-up fragment for the portal to integrate into the portal page. However, the end-user is completely shielded from the nitty-gritty details of WSRP -- all he knows is that he was able to seamlessly and easily integrate a new application into his portal.



Using WSRP services with WebSphere Portal
Points:
Portlet preferences – persistent storage
UDDI Registries