Building the Portlet
To build a JSR 168 portlet you begin by writing a GenericPortlet extension for every single portlet you develop. GenericPortlet is an abstract class that provides a default implementation for the portlet interface. Your GenericPortlet subclass should override at least one method, usually one of the following:
- processAction— Handles action requests.
- doView—Handles render requests when in View mode (Note: you'll see more about modes later).
- doEdit—Handles render requests when in Edit mode.
- doHelp—Handles render requests when in Help mode.
- init and destroy—Used to manage resources held for the life of the servlet.
Here's the code for a condensed version of the JSR 168 portlet class example,
StockQuotePortlet, which extends GenericPortlet, and overrides the
doView and
processAction methods:
package com.nuwave.portlets;
import javax.portlet.*;
...
public class StockQuotePortlet extends GenericPortlet {
public void doView(RenderRequest request,
RenderResponse response)
throws PortletException, IOException
{
The JSR 168 specification defines three portlet modes:
View,
Help, and
Edit. All portlets must support the
View mode, and do so by overriding the
doView() method as shown above. The
doView() method handles "render" requests by generating markup to display the portlet in the view mode. The RenderRequest and RenderResponse classes provide functionality similar to the HttpServletRequest and HttpServletResponse classes:
request.setAttribute("errors",
request.getParameter("errors"));
The preceding line demonstrates setting an attribute in and retrieving a parameter from the RenderRequest object. As you can see, it's similar to working with HTTPServletRequest objects. You'll use that
errors attribute later on in the JSP.
The next section of code obtains a PortletRequestDispatcher from the
portletContext for
viewQuote.jsp, and uses the
include method to pass the request to it. In this example,
viewQuote.jsp creates the display:
String nextURL = "/portlets/viewQuote.jsp";
PortletRequestDispatcher rd = getPortletContext().
getRequestDispatcher(nextURL);
rd.include(request, response);
} // end doView
...
The Portlet Container uses the
processAction method to handle a portlet's life cycle. The
processAction method handles client ActionRequests to update the portlet state. In this case, it will invoke the Xignite web service and store the data for the JSP to display:
public void processAction(ActionRequest request,
ActionResponse response)
throws PortletException, IOException {
try {
String query = request.getParameter("symbols");
// validate the query coming in
...
The code in the
try block gets the
symbols parameter from the request, and validates the query coming in (the validation code is not shown above; it's represented by the comment). The portlet uses the query string when invoking the Xignite web services.
You need to log into the external web service site to retrieve data. The example uses
portlet preferences to store the login values. Portlet preferences are persistent name/value pairs used to customize portlets. The following code retrieves the Xignite login info preferences from the request object and stores their values. You specify the preferences themselves in the
portlet.xml deployment descriptor discussed in the next section:
PortletPreferences prefs = request.getPreferences();
String username = prefs.getValue("xignite_username", "");
String password = prefs.getValue("xignite_password", "");
// Web service code goes here.
// It will create a quotes ArrayList variable containing
// the data retrieved from the web service.
request.getPortletSession().setAttribute(
"quotes", quotes);
}
catch (Exception e) {
response.setRenderParameter("errors", e.getMessage());
}
} // end processAction
You'll see the code that invokes the Xignite web services later in the article. For now, note the setting of the
quotes variable in the portlet session. Portlet sessions are very similar to servlet sessions. Each user session has its own unique PortletSession object, and you can set attributes on a portlet session object in the same fashion as on a ServletSession object. The
viewQuotes.jsp file uses the quotes object in the portlet session to display the data.
Portlet Deployment Descriptor
The JSR 168 specification requires the portlet deployment descriptor (
portlet.xml in this case) to have an entry for each portlet in the application. The descriptor provides a location to specify settings and preferences for each portlet. The descriptor file must reside in the
WEB-INF directory along with the
web.xml file.
The
portlet-app element is the root element of the
portlet.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app version="1.0"
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
The
portlet element starts the declaration of the sample portlet. The
portlet-name element contains the name you give to a portlet. It must be unique within the portlet application. The
portlet-class element specifies the fully qualified name of the class that implements the Portlet interface—in this example, the
StockQuotePortlet:
<portlet>
<description/>
<portlet-name>stockQuote_1</portlet-name>
<portlet-class>com.nuwave.portlets.StockQuotePortlet
</portlet-class>
The
supports element specifies the type of content that this portlet supports. The sample portlet supports HTML content and the
View mode:
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
The
portlet-preferences element declares any portlet preferences for this portlet. Here's where you specify the
xignite_username and
xignite_password preferences. You've already seen how to access these preferences in the code. For testing purposes, set the values to the username and password you specified during registration at Xignite's web site. Note: The password can be blank:
<portlet-preferences>
<preference>
<name>xignite_username</name>
<value>ENTER YOUR XIGNITE USERNAME</value>
</preference>
<preference>
<name>xignite_password</name>
<value>ENTER YOUR XIGNITE PASSWORD</value>
</preference>
</portlet-preferences>
Finally, close the
portlet and
portlet-app elements:
</portlet>
</portlet-app>
With the portlet built and configured, you can integrate the Xignite web service.