NEW!! FREE MOCK EXAM SIMULATORS FOR IBM PORTAL TEST 399 & IBM PORTLET CERTIFICATION EXAM TEST 829!!! Everything You Ever Wanted To Know About JSR-168 Portlet Development . . . PORTAL + TUTORIAL = www.portorials.com
Many textbooks and references that talk about ServletConfig and ServletContext objects, which essentially correspond to the PortletConfig and PortletContext objects, gloss over the power of these objects, and simply give lip-service to the act of reading parameter values from deployment descriptors. Well, I?m not going to do that. I?m going to show you a very simple example of a templatized portlet, that can have a profound effect on a developer?s ability to generate a multitude of useful and configurable portlets.
This is a very kewl tutorial. I highly recommend it!
Please support our site, link to us, buy some books, and remember:
Happy Java!
Download the Code!!! (Scroll down and view the code)
Config Objects We?ve covered just about every object in the
Portlet API, with the exception of two of the most important ones. It?s
hard to believe we?ve made it this far without touching upon them. The
JSR-168 API defines two configuration objects, namely the PortletContext
and the PortletConfig objects. In this chapter, I?m also going to throw
the PortalContext into the mix as well, as it is phonetically pretty
close to PortletContext. J It?s pretty easy to get the two of them
confused. The PortalContext The PortalContext is a relatively straight
forward object containing five important methods. These methods
basically represent a handle from the portlet we code, bac to the Portal
Server. From the PortalContext, we can discover the supported modes of
the portal (just in case we want to code a custom portlet mode), along
with the supported window states. This is good information to know when
creating a portlet that may be deployed to a variety of different portal
servers. The PortletConfig Interface The PortletConfig object is really
just a handle back to the information about a portlet that is configured
in the portlet.xml file. Methods like getPortletName(),
getResourceBundle() and getInitParameters() are all methods that
essentially read information that is written about the portlet in the
portlet.xml deployment descriptor. Since all of these parameters come
from a text file that cannot be edited at runtime, all of these
parameters are read-only. If you want to change the data obtained by
PortletConfig, you need to edit the portlet.xml file and bounce your
portlet application. The PortletConfig becomes most interesting when you
use it for initialization parameters. The method getInitParameters() can
pull data from the portlet.xml deployment descriptor based upon the name
of a name-value pair. The data is always returned as a string; after
all, you can?t exactly code objects into the portlet.xml file. The neat
thing about the PortletConfig is that it is common to the Portlet,
regardless of the user interacting with the portlet. Unike the
PortletSession object, where data is unique to the user, and not
persisted, or the PotletRequest, where data is unique to a user, but
purged after every request-response cycle, data obtained from the
PortletConfig is always the same, regardless of the user invoking the
Portlet. The only way to change the data pulled from the PortletConfig
object is to phycially edit the portlet.xml file, which isn?t possible
while an application is running. The PortletContext and the
ServletContext Similar to the PortletConfig interface, the
PortletContext has a method called getInitParameters(), which can spit
out read-only String values that are configured in a deployment
descriptor. Which deployment descriptor, you ask? Well, that?s a very
good question. The PortletContext is really just a wrapper placed around
the glorious ServletContext from the Servlet and JSP API. The true
nature of the PortletContext is revealed when you discover that the
init-parameters the PortletContext reads, are actually pulled from the
same place the ServletContext init-parameters are pulled: the web.xml
file. Yes, init-parameters for the PortletContext are actually
configured in the deployment descriptor of the web module. So, what
exactly is the PortletContext? Well, essentially, the PortletContext
represents the shared space in which all of the portlets associated with
a common war file reside. So, if information is stored in the
PortletContext of a portlet application, any portlet that is deployed as
part of that portlet application can access that information. The
PortletContext and the Portlet Application So, any portlet deployed as
part of a common war file can share and access information made
available through the PortletContext. Now, this doesn?t mean every
portlet running on a portal server has access to the same portlet
context. Every portlet application, which essentially means all of the
portlets that are defined in a common portlet.xml file, has a common
PortletContext. However, a portlet defined in one portlet.xml file will
never be able to access the PortletContext of a portlet defined in a
different portlet application. For example, one resource that all
Portlets and JSPs in a portlet application need access to is the
PortletRequestDispatcher, which has been used many times to allow a
portlet delegate to a JSP for markup generation. The
PortletRequestDispatcher is a service that must be available to all
portlets running in a portlet application, so it only makes sense that
it be made available through the PortletContext. Another helpful service
made available through the PortletContext is the logging service. Two
overloaded log() methods are available to portlets through the
PortletContext. Messages written through this logging service are
written to a special log file, as defined by the portlet container
vendor. The PortletContext also provides utility methods, such as
getMajorVersion() and getMinorVersion(), for figuring out what version
of the Portlet API your application is using; but by far, the most
powerful methods of the PortletContext are the ones that provide access
to the read-only initialization parameters, and the editable runtime
attributes that can be added and deleted from the PortletContext. Class
Diagram for he PortletContext Interface Templatized Portlets Many
textbooks and references that talk about ServletConfig and
ServletContext objects, which essentially correspond to the
PortletConfig and PortletContext objects, gloss over the power of these
objects, and simply give lip-service to the act of reading parameter
values from deployment descriptors. Well, I?m not going to do that. I?m
going to show you a very simple example of a templatized portlet, that
can have a profound effect on a developer?s ability to generate a
multitude of useful and configurable portlets. Take a look at the
following GenericTaxPortlet. How many portlets do you see there? One?
Well, you?re wrong ? there are hundreds. package com.examscam.portlet;
import java.io.*;import javax.portlet.*; public class GenericTaxPortlet
extends GenericPortlet { protected void doView(RenderRequest request,
RenderResponse response) throws PortletException, IOException {
response.setContentType(?text/html?); PrintWriter out =
response.getWriter(); PortletContext context = this.getPortletContext();
PortletConfig config = this.getPortletConfig(); String fedRate =
context.getInitParameter("fedrate"); String regionName =
context.getInitParameter("regionname"); String regionalRate =
config.getInitParameter("regionalrate"); out.print("
<BR>The federal tax rate is: " + fedRate); out.print("
<BR>The " + regionName + " tax rate is: ");
out.print(regionalRate); } }
Deployment Descriptors and InitParameters The GenericTaxPortlet reads in
three values from the deployment descriptors, namely fedrate and
regionname from the web.xml file, and regionalrate from the portlet.xml
file. But imagine if we wanted to create a bunch of portlets, based on
the GenericTaxPortlet, that displayed the federal and state tax
obligations for each of the fifty U.S. states? Well, we could create an
entry in the portlet.xml file for each state, and configure each state
with a different tax rate. We could have one entry for the
FloridaTaxPortlet, another for the TexasTaxPortlet, and a third for the
NevadaTaxPortlet. We could configure each as a separate portlet in the
portlet.xml file, point to the same GenericTaxPortlet as the
implementing class, and provide a unique value for each state?s tax
rate. Okay, these three states are bad examples, because none of them
actually have a state tax, but you get the point! """
<portlet>
<description>OhioTaxPortlet</description><portlet-name>OhioTaxPortlet</portlet-name>
<display-name>OhioTaxPortlet</display-name>
<portlet-class>
com.examscam.portlet.GenericTaxPortlet </portlet-class>
<init-param>
<name>regionalrate</name><value>4</value>
</init-param>
<supports><mime-type>text/html</mime-type><portlet-mode>view</portlet-mode></supports>
<supported-locale>en</supported-locale> <portlet-info>
<title>Ohio</title>
</portlet-info> </portlet>
<!-- You can make as many portlets as you like!!!-->
<portlet>
<description>FloridaTaxPortlet</description><portlet-name>FloridaTaxPortlet</portlet-name>
<display-name>FloridaTaxPortlet</display-name>
<portlet-class>
com.examscam.portlet.GenericTaxPortlet </portlet-class>
<init-param>
<name>regionalrate</name><value>5</value>
</init-param>
<supports><mime-type>text/html</mime-type><portlet-mode>view</portlet-mode></supports>
<supported-locale>en</supported-locale> <portlet-info>
<title>FloridaTaxPortlet</title>
</portlet-info> </portlet>
<portlet>""<name>regionalrate</name><value>5</value></portlet>
"" Web Deployment Descriptor (web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID"> <display-name>US
TaxProject</display-name> <context-param>
<param-name>fedrate</param-name>
<param-value>35</param-value> <description>Federal
Tax Rate</description> </context-param>
<context-param> <param-name>regionname</param-name>
<param-value>state</param-value> <description>Region
Name</description>
</context-param> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> </web-app>
Portlet Deployment Descriptor (portlet.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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"
id="com.examscam.portlet.GenericTaxPortlet.fb9b06d0f0">
<portlet> <description>GenericTaxPortlet</description>
<portlet-name>GenericTaxPortlet</portlet-name>
<display-name>GenericTaxPortlet</display-name>
<portlet-class> com.examscam.portlet.GenericTaxPortlet
</portlet-class>
<init-param> <name>regionalrate</name>
<value>5</value> </init-param> <supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode> </supports>
<supported-locale>en</supported-locale> <portlet-info>
<title>GenericTaxPortlet</title>
</portlet-info> </portlet> </portlet-app>
Repackaging the WAR So, by creating multiple entries in the portlet.xml
file, we can create a multitude of portlets based upon the
GenericTaxPortlet. But all of these portlets are really focused on the
United States. What about other countries? Well, we could configure all
of the American states in one portlet.xml file, and export that entire
portlet application as a single war file, perhaps called
USTaxesPortletApp.war. We could then create a second portlet application
for Canada, called the CanadianTaxesPortletApp.war. And if people
outside of North American started buying my books, we could create
portlet applications for those countries too. For the
CanadianTaxesPortletApp, our portlet.xml file would have entries for
each of the Canadian provinces, and the web.xml file, where
PortletContext parameters are configured, would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID"> <display-name>Canadian
TaxProject</display-name>
<context-param> <param-name>fedrate</param-name>
<param-value>45</param-value>
<description>Federal Tax Rate</description>
</context-param> <context-param>
<param-name>regionname</param-name>
<param-value>provincial</param-value>
<description>Region Name</description>
</context-param> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> </web-app>
PortletContext Attributes Both the PortletContext and PortletConfig
objects can read information from deployment descriptors, but only the
PortletContext provides a scope for storing readable and writable
properties. The PortletRequest provides a scope for storing user centric
information that is purges as soon as the current request-response cycle
is completed. The PortletSession provides a transient data storage
mechanism that can store user-centric data for as long as the user is
visiting our website. The PortletPreferences object provides permanent
storage for user preferences. But each of these mechanisms work on a
per-user basis. How can information be shared across all users, and all
portlets, that are part of the same portlet application (aka, packaged
in the same war file) ? Well, the PortletContext provides a
getAttribute() and setAttribute() method that allows objects to be
stored, and shared across all users and all portlets in a portlet
application. The PortletContext, and its close cousin, the
ServletContext, are two incredibly powerful scope storage mechanisms,
and unfortunately, two of the most under-utilized. I love the
PortletContext, and believe that it should be used more often in
applications. There is one drawback to the PortletContext though. The
PortletContext is not always synchronized across JVMs in a cluster. As a
result, objects placed in the PortletContext should be largely read
from, and rarely written to. On my websites, I provide a variety of
online mock exams for certification preparation. In my Java apps, I
always store the set of questions in the PortletContext or
ServletContext. The questions are loaded into the context as soon as the
application starts up, and are not really ever changed at runtime. Of
course, almost every JSP, Servlet, Portlet, Filter, or other web
artifact must access the exam object, so having it in the context is
very convenient. Use the PortalContext when it makes sense. Your users
will love you for it! Question 7-1 For a given portlet definition, how
many instances of that portlet should run on a portal server? ˇ a) one
instance per JVMˇ b) one instance per userˇ c) one instance per pageˇ d)
one instance every time the portlet is rendered Answer a) is correct.
Given a portlet definition, only one instance of that portlet should
ever be instantiated. In a distributed environment, where multiple JVMs
service an application, the specification allows for one instance per
JVM. Question 7-2 When developing an application that needs to be
customized by the user, but will also need data to be formatted for
printing what type of solution is best? ˇ a) a single portlet supporting
multiple portlet statesˇ b) a Portlet solution based on the Struts
portal frameworkˇ c) a single portlet supporting multiple portlet modesˇ
d) a portlet solution that relies heavily on portlet services Answer c)
is correct. Custom portlet modes can be used for such features as
printing or providing custom about message. Be aware though that not
only must your portlet provide an implementation for the custom mode,
but you portal server must support the custom mode as well. Question 7-3
If a PortletException is thrown during the init method of a portlet ¨ a)
the portal container may re-attempt to initialize the portlet¨ b) the
portlet container my not attempt to re-initialize the portlet¨ c) the
destroy method will not be called¨ d) the destroy method will be called
to clean up any initialized resources Answers a) and c) are correct. If
a PortletException is thrown during the init method, the destroy method
is not called, because initialization is considered to be unsuccessful.
Furthermore, the container may attempt to re-initialize the Portlet.
Question 7-4 PortletConfig initialization parameters are: ¨ a) defined
in the web.xml file¨ b) defined in the portlet.xml file¨ c) read only
and cannot be changed at runtime¨ d) read/write, but may get out of sync
across multiple JVMs Answers b) and c) are correct. In the old IBM API,
PortletConfig was defined in the web.xml file, but with JSR-168,
initialization parameters are all maintained in the portlet.xml file.
Also, initialization parameters for a portlet are read only.
PortletConfig does not have a problem being managed across JVMs.
Synchronization across JVMs is only a problem with the PortletContext.
Question 7-5 The PortletConfig object is ˇ a) shared amongst all portlet
instancesˇ b) unique to a particular portlet instanceˇ c) unique to a
particular userˇ d) is unique to a particular session Answer b) is
correct. PortletConfig provides initialization parameters to a
particular portlet instance. That data is then available to any user,
session or any method call made at any time to that particular portlet.
Question 7-6 Which of the following statements are true: ¨ a) the
PortletContext is accessed through the this of a portlet¨ b) the
PortletConfig is accessed through the this of a portlet¨ c) the
PortletContext is accessible through the PortletConfig¨ d) the
PortletConfig is accessible through the PortletContext Answers a), b)
and d) are the correct answers. There is a getPortletContext() method in
the PortletConfig object, but the PortletContext method has not
facilities for accessing the PortletConfig object. Question 7-7 Where is
a PortletPreference defined as being read only. ˇ a) programmatically
through the PortletPreferences objectˇ b) by adding a read-only
parameter to the portlet.xml fileˇ c) by adding a read-only parameter to
the web.xml fileˇ d) PortletPreferences are always editable Answer b) is
correct. There is no programmatic way to set a PortletPreference to be
read-on; this can only be done by setting the preference through the
portlet.xml file, and subsequently adding a tag indicating that the
preference is read only. Question 7-8 Which of the following methods is
triggered every time a portlet is displayed in view mode? ˇ a) initˇ b)
destroyˇ c) doViewˇ d) processAction Answer c), doView, is correct. Init
and destroy are only called once in the lifecycle of a portlet. The
doView method is invoked every time a portlet is viewed in view mode.
The processAction is only invoked when an action URL is used by the
client, which may or may not happen when a portlet is asked to be
displayed in view mode. Answer 4xxx-1xxx The PortalContext: ¨ a) can
provide a list of window states supported by the portal¨ b) can provide
a list of portlet modes supported by the portal¨ c) provides access to
the RequestDispatcher¨ d) provides access to the portal logging
mechanism Options a) and b) are correct. The PortalContext has five
methods, including getPortalInfo, getPropertyNames, getProperty,
getSupportedPortletModes and getSupportedWindowStates. The object used
to access the PortletRequestDispatcher and the portal logging mechanism
is the similarly named PortletContext object. Answer 7-1 For a given
portlet definition, how many instances of that portlet should run on a
portal server? ˇ a) one instance per JVMˇ b) one instance per userˇ c)
one instance per pageˇ d) one instance every time the portlet is
rendered Answer a) is correct. Given a portlet definition, only one
instance of that portlet should ever be instantiated. In a distributed
environment, where multiple JVMs service an application, the
specification allows for one instance per JVM. Answer 7-2 When
developing an application that needs to be customized by the user, but
will also need data to be formatted for printing what type of solution
is best? ˇ a) a single portlet supporting multiple portlet statesˇ b) a
Portlet solution based on the Struts portal frameworkˇ c) a single
portlet supporting multiple portlet modesˇ d) a portlet solution that
relies heavily on portlet services Answer c) is correct. Custom portlet
modes can be used for such features as printing or providing custom
about message. Be aware though that not only must your portlet provide
an implementation for the custom mode, but you portal server must
support the custom mode as well. Answer 7-3 If a PortletException is
thrown during the init method of a portlet ¨ a) the portal container may
re-attempt to initialize the portlet¨ b) the portlet container my not
attempt to re-initialize the portlet¨ c) the destroy method will not be
called¨ d) the destroy method will be called to clean up any initialized
resources Answers a) and c) are correct. If a PortletException is thrown
during the init method, the destroy method is not called, because
initialization is considered to be unsuccessful. Furthermore, the
container may attempt to re-initialize the Portlet. Answer 7-4
PortletConfig initialization parameters are: ¨ a) defined in the web.xml
file¨ b) defined in the portlet.xml file¨ c) read only and cannot be
changed at runtime¨ d) read/write, but may get out of sync across
multiple JVMs Answers b) and c) are correct. In the old IBM API,
PortletConfig was defined in the web.xml file, but with JSR-168,
initialization parameters are all maintained in the portlet.xml file.
Also, initialization parameters for a portlet are read only.
PortletConfig does not have a problem being managed across JVMs.
Synchronization across JVMs is only a problem with the PortletContext.
Answer 7-5 The PortletConfig object is ˇ a) shared amongst all portlet
instancesˇ b) unique to a particular portlet instanceˇ c) unique to a
particular userˇ d) is unique to a particular session Answer b) is
correct. PortletConfig provides initialization parameters to a
particular portlet instance. That data is then available to any user,
session or any method call made at any time to that particular portlet.
Answer 7-6 Which of the following statements are true: ¨ a) the
PortletContext is accessed through the this of a portlet¨ b) the
PortletConfig is accessed through the this of a portlet¨ c) the
PortletContext is accessible through the PortletConfig¨ d) the
PortletConfig is accessible through the PortletContext Answers a), b)
and d) are the correct answers. There is a getPortletContext() method in
the PortletConfig object, but the PortletContext method has not
facilities for accessing the PortletConfig object. Answer 7-8 Which of
the following methods is triggered every time a portlet is displayed in
view mode? ˇ a) initˇ b) destroyˇ c) doViewˇ d) processAction Answer c),
doView, is correct. Init and destroy are only called once in the
lifecycle of a portlet. The doView method is invoked every time a
portlet is viewed in view mode. The processAction is only invoked when
an action URL is used by the client, which may or may not happen when a
portlet is asked to be displayed in view mode. Answer 4xxx-1xxx The
PortalContext: ¨ a) can provide a list of window states supported by the
portal¨ b) can provide a list of portlet modes supported by the portal¨
c) provides access to the RequestDispatcher¨ d) provides access to the
portal logging mechanism Options a) and b) are correct. The
PortalContext has five methods, including getPortalInfo,
getPropertyNames, getProperty, getSupportedPortletModes and
getSupportedWindowStates. The object used to access the
PortletRequestDispatcher and the portal logging mechanism is the
similarly named PortletContext object.