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.
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.
|This article is an excerpt from an Early Access Edition of the book “Portlets in Action” (Manning Publications; ISBN: 9781935182542), written by Ashish Sarin.|
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
|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.
Figure 1: 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.
At #1, a request for portlet A is received from a user of the Web portal. The request may be generated because the user clicked a hyperlink or submitted a form. At #2, the request is found to be a render request for portlet A, which the portal server sends to the portlet container. Because the render request is for portlet A, only the render request-processing phase applies to the request. As we mentioned earlier, the render request-processing phase maps to the portlet’s
render method. It results in an invocation of portlet A’s
render method, at #3. The
render method of portlet A generates the content for portlet A and returns it to the portlet container. At #4, even though the render request was for portlet A, the portlet container goes ahead and invokes portlet B’s
render method as well. At #5, the portlet container returns the contents of both portlets A and B to the portal server, which combines the content of both portlets A and B, puts window decoration around their content, composes a new portal page, which shows latest content from both portlets A and B, and sends the new portal page to the client browser. At #7, the request for portlet A is received from the Web portal. The request is found to be action request, which is sent by the portal server to the portlet container, at #8. Since the action request is for portlet A, the action request-processing phase applies to the request. As we mentioned earlier, the action request-processing phase maps to the portlet’s
processAction method. It results in an invocation of portlet A’s
processAction method, at #9. Even though the action request was for portlet A, the portlet container invokes the
render method of portlets A and B, at #10 and #11, respectively. The order in which the render methods of the portlets are invoked is undefined; that is, portlet A’s render method may be called before portlet B’s render method or vice versa. At #12, the portlet container returns the content generated by the
render methods of portlets A and B to the portal server. At #13, the portal server aggregates the content from portlets A and B, puts window decoration around their content, composes a new portal page, which shows latest content from both portlets A and B, and sends the new portal page to the client browser.
Figure 1 is a simplified version of an actual request-processing lifecycle in portlets because it only covers the render and action phases.
At #1, request for a portlet is received by the portlet container. The portlet container invokes the portlet, which in turn generates the content in its render phase. At #2, the portlet sets portlet URL A as part of its generated content. Because requests can only be sent to a portlet using self-referencing portlet URLs, the portlet instance is responsible for setting portlet URLs as part of it generated content. At #3, the user’s action results in a send request to portlet URL A, which results in an invocation of the portlet at #4. At #5, the portlet creates fresh content and sets portlet URL B as part of its content.
You may have noticed that figure 2 doesn’t show how the request was received by the portlet for the first time. A question arises at this point: how does a portlet receive a request to generate the content for the first time? A portlet can display a message without requiring us to explicitly send a request to the portlet. This happens because the content generation request (called render request) is sent to the portlet by the portal server when a user adds a portlet to a portal page or visits a portal page containing portlet(s).
It is not possible for a portlet to generate URLs referring to other portlets in the portal.
Let’s now look at the different URL types in portlets.
Portlet URL types
The request-processing cycle for a portlet is kicked off when the user submits a request to the portlet URL by clicking a hyperlink or submitting a form. Portlet URLs are related to the portlet request types that we discussed earlier in this article. Portlet URLs are classified by the portlet specification based on the requested action from the portal page. The three different types of portlet URLs are defined as follows.
- render URL — intended for asking a portlet instance to generate markup (like HTML, XML, or WML) based on its current state. The request sent to the portlet by a render URL is referred to as a render request.
- action URL — intended for action processing, which results in a state change on the server. The request sent to the portlet by an action URL is referred to as an action request.
- resource URL — intended for rendering content or retrieving resources (like image files). Depending upon the application requirement, a resource URL may be used for updating the application state. The request sent to the portlet by a resource URL is referred to as a resource request.
Portlets don’t have an event URL type for sending event requests to portlets.
A portlet URL is like any other URL but difficult to comprehend because it is generated by the portlet container for internal use. When a request is submitted from the portal (by a user’s clicking of a link or a button), the portlet URL (associated with the link clicked or form submitted) is interpreted by the portlet container to identify the target portlet instance and the type of request (action, render, or resource) received from the client. The following
form tag from HTML rendered by a portlet shows portlet URL in the
<form id="search" name="… " action="http://localhost:8080/web/guest/home?p_p_id=HelloWorldPortlet_WAR_helloWorld_INSTANCE_MrP9&p_p_lifecycle=1&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_HelloWorldPortlet_WAR_helloWorld_INSTANCE_MrP9_action=someAction" method="post">
It is important to understand the purpose of different portlet URLs because, based on the URL type, corresponding lifecycle methods (like
processAction) are invoked on the portlet instance.
The different lifecycle interfaces in a portlet help to separate responsibilities for generating content, processing action, handling a received event, and serving resources in your portlet class. A clear understanding of the purpose of different lifecycle interfaces and methods helps you to segregate your logic appropriately in your portlet class. For instance, the
processAction method is intended for processing action and not for generating content. If you attempt to generate content by dispatching a request to a JSP page (using
PortletRequestDispatcher) or by directly writing to the response output stream, any such effort to generate content will be ignored by the portlet container. Similarly, the
render method is for generating content and not for processing user actions. If you write action-processing logic in the
render method instead of the
processAction method, action processing will take place every time the portlet’s
render method is invoked (either because the user refreshed the portal page or the action request was sent to another portlet on the same portal page), which is undesirable.