Basics
The portlet container is responsible for the layout and
appearance of the portlets. The portlet defines only the content of
the window that is assigned to it by the continer.
Portlet containers typically provide three display modes
for a portlet: normal, maximized and minimized.
The Portlet interface defines the methods that each portlet
must implement.
interface Portlet {
void init(PortletConfig config);
void destroy();
void processAction(ActionRequest req, ActionResponse resp);
void render(RenderRequest req, RenderResponse resp);
}
On initialization, the container calls the portlet's init()
method, providing it with a PortletConfig parameter, which can be used
to access the initialization parameters and ResourceBundle defined in
the deployment descriptor.
interface PortletConfig {
String getInitParameter(String name);
Enumeration getInitParameterNames();
PortletContext getPortletContext();
String getPortletName();
ResourceBundle getResourceBundle(Locale locale);
}
Two methods are defined for handling requests. Action request
are handled by processAction() and render requests are handled by
the render() method. These correspond to action URLs and render URLs.
If the user triggers an action request, the container will call
proceessAction() and then render(). A render request results in a call
to render only. The intention is that render requests are for redisplaying
the current content only, while action requests are to request services or
change the portlet state. A portlet may need to be displayed many times
while a user is working with other portlets. In general, the portlet
state should not change as a result of a render request.
Each portlet may operate in one of three standard modes, or
in other modes customized by the portlet container. The three standard
modes are VIEW, EDIT and HELP. In general, VIEW is for display, EDIT is
for interacting with the portlet, and HELP is for get help information
about the portlet.
The abstract class GenericPortlet implements Portlet, and provides
default functionality and convenience methods.
public abstract class GenericPortlet {
void processAction(ActionRequest req, ActionResponse resp);
void doView(RenderRequest req, RenderResponse resp);
void doEdit(RenderRequest req, RenderResponse resp);
void doHelp(RenderRequest req, RenderResponse resp);
String getTitle(RenderRequest req);
...
}
The getTitle() method is called to get the title to display
in the portlet's title bar.
When minimized, none of the render methods are called.
The portlet container can unload a portlet at any time. Before
doing so, however, it must call the destroy() method.
Portlet URLs
Since the portlet container needs to manage the URLs of the
portlets being displayed, portlets must use an API to generate URLS.
Furthermore, GET URLs shouldn't be used since internal state may need
to be added to URLs.
URLs are created using the createActionURL() and createRenderURL()
of RenderResponse. These return PortletURL objects. Parameters are defined
via setParameter() and setParameters(). Window state changes can be
requested via setWindowState().
PortletURL url = resp.createRenderURL();
url.setParameter("abc", "xyz");
url.setWindowState(WindowState.MAXIMIZED);
String s = url.toString();
Request Processing
The main interface is PortletRequest, and ActionRequest and
RenderRequest are both subinterfaces of PortletRequest.
PortletRequest defines methods for accessing parameter values
from the request.
interface PortletRequest {
...
String getParameter(String name);
String[] getParameterValues(String name);
Enumeration getParameterNames();
Map getParameterMap();
...
}
PortletRequest also defines methods used to set and get
attributes, which can be used to share information with other compenents
such as servlets or JSP pages.
interface PortletRequest {
...
Object getAttribute(String name);
void setAttribute(String name, Object value);
void removeAttribute(String name);
Enumeration getAttributeNames();
...
}
PortletRequest provides methods for determining the current mode
and window state.
interface PortletRequest {
...
PortletMode getPortletMode():
WindowState getWindowState();
...
}
Corresponding to the requests, there are the PortletResponse,
ActionResponse and RenderResponse interfaces.
The encodeURL() method of PortletResponse is used to encode
URLs used to access other resources within the application, such as
servlets, images and static files. The container will add in any
addition state information that is required.
The ActionResponse response is used by processAction().
This method can send a redirect, change the portlet mode, change the
window state, and set parameters which will be included in subsequent
render requests.
interface ActionResponse {
...
void sendRedirect(String location);
void setPortletMode(PortletMode mode);
void setWindowState(WindowState state);
void setRenderParameter(String name, String value);
void setRenderParameter(String name, String[] values);
void setRenderParameters(Map parameters);
...
}
The RenderResponse object can be used to set the content type,
the portlet title, and buffering parameters. It can write directly to
the output stream, using getPortletOutputStream() or getWriter().
Portlet Preferences
Portlet preferences provide a mechanism for portlets to persist
data as a set of name value pairs. The implementation is provided by the
portlet container. The specification is a bit vague on the scope: seems to
be that each user has his/her own preferences object for each portlet, but
it's not clear whether two visible portlets of the same time share the
same preferences object.
The PortletPreferences object is accessed via PortletRequest's
getPortletPreferences() method. Various methods are provided for getting,
setting and saving preferences.
interface PortletPreferences {
Map getMap();
Enumeration getNames();
String getValue(String name, String default);
String[] getValues(String name, String[] defaults):
boolean isReadOnly(String name);
void reset(String name);
void setValue(String name, String value);
void setValue(String name, String[] values);
void store();
}
Preferences can be initialized from the portlet.xml configuration
file.
<portlet>
...
<portlet-preferences>
<preference>
<name>AAA</name>
<value>yyy</value>
<value>zzz</value>
<read-only>true</read-only>
</preference>
...
</portlet-preferences>
</portlet>
Sessions
Portlets can share information with the http session object by
means of the PortletSession object. This object provides two scopes,
application scope and portlet scope. The application scope is global, and
includes all session information placed by other web components such as
servlets on the HttpSession object. The portlet scope is also global,
but have special keys that effectively relegate the entries to a portlet
specific namespace.
PortletSession session = req.getSession();
session.setAttribute("franz", "liszt", PortletSession.APPLICATION_SCOPE);
session.setAttribute("holy", "lizards", PortletSession.PORTLET_SCOPE);
There are also methods without scopes; these default to the
portlet scope. The PortletSession object also provides many methods
available from HttpSession; these give the same results.
interface PortletSession {
Object getAttribute(String name);
Object getAttribute(name, int scope);
Enumeration getAttributeNames();
Enumeration getAttributeNames(int scope);
void removeAttribute(String name);
void removeAttribute(String name, int scope);
void setAttribute(String name, Object value);
void setAttribute(String name, Object value, int scope);
long getCreationTime();
long getLastAccessedTime();
int getMaxInactiveInterval();
PortletContext getPortletContext();
void invalidate();
boolean isNew();
void setMaxInactiveInterval(int interval);
}
Dispatching to Servlets/JSPs
A portlet may dispatch to a servlet or JSP for creating content,
by means of a PortletRequestDispatcher object, obtained from the
PortletContext object.
- getRequestDispatcher() - provide a path within the portlet application, beginning with '/', relative to the portlet context root
- getNamedDispatcher() - provide a servlet name
The URL can contain a query string; the query parameters are
added to (and override, in the case of duplicates) the set of existing
render parameters.
String url = "/something.jsp?count=123";
PortletContext ctx = getPortletContext();
PortletRequestDispatcher rd = ctx.getRequestDispatcher(url);
rd.include(req, resp);
Within a JSP page that provides content for a portlet, the
portlet tag library can be used. It is declared as follows:
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
The defineObjects tag had no content.
It makes the following variables available
in the JSP page:
- renderRequest
- renderResponse
- portletConfig
The actionURL tag creates a URL which triggers an action
request in the current portlet. Parameters are added via param children;
the following parameters are supported:
- windowState: normal, minimized, maximized
- portletMode: edit, help, view, ...
- var: name of the variable exported
- secure: true, false
The renderURL tag creates a URL which triggers a render request
in the current portlet. It has the same parameters as actionURL.
Example:
<portlet:defineObjects/>
<portlet:actionURL var="url" portletMode="view"/>
<form method="POST" action="<%= url %>">
Current mode: <%= renderRequest.getPortletMode() %>
...
Configuration
The portlets are configured in WEB-INF/portlet.xml. Best just
to give an example.
<portlet-app
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
<portlet>
<description>Fifth Test</description>
<portlet-name>TestPortlet5</portlet-name>
<display-name>Test 5</display-name>
<portlet-class>org.apache.pluto.examples.TestPortlet5</portlet-class>
<init-param>
<name>check</name>
<value>true</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-mode>EDIT</portlet-mode>
<portlet-mode>HELP</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>rb</resource-bundle>
<portlet-info>
<title>whatever</title>
</portlet-info>
</portlet>
...
</portlet-app>