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
In a good model-veiw-controller type of application, a Java centric component should never be polluted with lots of lousy html.
With typical servlet and struts based applications, html is usually generated by a Java Server Page (JSP); in this regard, portlet applications are no different.
However, portlet applications do present some unusual complications when deferring to a JSP for markup generation.
How does a JSP link back to a specific portlet on a page? How does a portlet call a JSP? How do we gain access to the portlet specific PortletRequest and PortletResponse object in JSP?
This tutorial deals with basic JSP development, and the issues that present themselves when deferring to a JSP for markup generation.
Please support our site, link to us, buy some books, and remember:
Happy Java!
Download the Code!!! (Scroll down and view the code)
Here's a link to download the completed solution. This solution does not have the defineObjects tag in the JSP: JSPDisplayNoDefineObjectsTag.war
Here's a link to download the completed solution. This solution does have the defineObjects tag in the JSP: JSPDisplayNoDefineObjectsTag.war
The war file was created using IRAD 6, but it's a JSR-168
compliant portlet application, so feel free to deploy it anywhere.
The JSPDisplay Portlet
package com.examscam.portlet;
import java.io.*;
import javax.portlet.*;
/**
*
* A sample portlet based on GenericPortlet
*
*/
public class JSPDisplayPortlet extends GenericPortlet {
<B>Welcome to this simple JSP<B><BR>
We did some snooping on you.<BR>
This is what we learned about your browser:<I>
<%=renderRequest.getProperty("user-agent")%>
</I><BR>
And we know what language you speak, it's: <I>
<%=renderRequest.getLocale().getDisplayLanguage()%>
</I>
Rendering a View with Java Server Pages
In a good model-veiw-controller type of application, a Java centric
component should never be polluted with lots of lousy html.
With typical servlet and struts based applications, html is usually
generated by a Java Server Page (JSP); in this regard, portlet
applications are no different.
However, portlet applications do present some unusual complications when
deferring to a JSP for markup generation.
How does a JSP link back to a specific portlet on a page? How does a
portlet call a JSP? How do we gain access to the portlet specific
PortletRequest and PortletResponse object in JSP?
This chapter deals with basic JSP development, and the issues that
present themselves when deferring to a JSP for markup generation.
Deferring to a JSP for Markup Generation
While accessing the PrintWriter from the request object and printing
content directly back to the client in the doView method of a portlet is
easy to do, it certainly isn?t a best practice.
We have been spoiled so far with portlets that are relatively light on
html tags. However, for content generation, a portlet should defer to a
Java Server Page (JSP). JSPs are web centric artifacts that are written
largely in static html, but can be interspersed with Java code to make
them more interactive.
Figure 3-1 A Sample Java Server Page (JSP), welcome.jsp
A JSP is mostly markup, with a little bit of Java code (in bold)
interspersed. Java Server Pages facilitate the development of complex,
dynamic web pages.
<%@ page session="false" contentType="text/html"
%>
<B>Welcome to this simple JSP<B><BR>
We did some snooping on you.<BR>
This is what we learned about your browser:
<I><BR> <%=request.getHeader("user-agent")%>
</I><BR>
And we know what language you speak, it's:
<I> <%=request.getLocale().getDisplayLanguage()%> </I>
Invoking the welcome.jsp from a Portlet
While the concept of delegating to a JSP for view generation is
relatively simple and straight forward, the code is actually a little
bit intimidating. Assuming the code from Figure 3-1 was saved in a file
named welcome.jsp, and that welcome.jsp file was saved in the root of
the war, invoking the welcome.jsp would require the following lines of
code in a portlet:
String url = "welcome.jsp";
getPortletContext()
.getRequestDispatcher(url).include(request,response);
Using a JSP for Markup Generation
When a particular portlet is requested, the custom coded Java class that
extends GenericPortlet, and is specified in the portlet.xml file, will
be invoked by the portal server. The portlet class is then responsible
for delegating to a JSP for markup generation. This is done using the
include method of the PortletRequestDispatcher, during the portlet?s
rendering phase.
The full code for the JSPDisplay portlet that forwards to the
welcome.jsp file is as follows:
package com.examscam.portlet;
import java.io.*; import javax.portlet.*;
public class JSPDisplay extends GenericPortlet {
protected void doView
(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
String url = "/welcome.jsp";
getPortletContext()
.getRequestDispatcher(url).include(request,response);
}
}
Where is the Portal Finding the JSP?
Legacy portal development tools would pull jsp files from a variety of
different folders, depending upon the client device and the preferred
language of the user making the request. For JSR-168 portlets, the
PortletRequestDispatcher, quite sensibly searches for jsp files starting
from the root of the war.
So, with the JSPDisplay portlet, the welcome.jsp file would be found
right there in the root.
JSP Deferment and Multiple Markup Support
For supporting multiple markup languages, it is customary, and automatic
with the portlet wizards of many rapid application development tools,
that subdirectories exist for each of your markup languages, under a
folder named jsp. By following this convention, multiple markup
languages can be easily integrated by simply creating new JSP files in
the appropriately named subfolders, and using these JSPs at the
appropriate times.
Figure 3-2
A well formed folder structure helps in the development of multi-device
capable portlets.
Deployment Descriptor for JSPDisplay Portlet
Assuming the JSPDisplay portlet is packaged in its own war file, the
portlet.xml file for the JSPDisplay portlet would be as follows:
<?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.JSPDisplay.9afc93cee0" >
<portlet>
<description>JSPDisplay</description>
<portlet-name>JSPDisplay</portlet-name>
<display-name>JSPDisplay</display-name>
<portlet-class>
com.examscam.portlet.JSPDisplay
</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info><title>JSPDisplay</title></portlet-info>
</portlet>
</portlet-app>
Something Wrong with our welcome.jsp
Portlets build extensively upon the Servlet and JSP API, and the
welcome.jsp file in Figure 3-1 was coded as though it were part of a
typical Servlet and JSP application. When you?re doing portlet
development, not respecting your jsp files as portlet artifacts is a
very bad thing.
A Java Server Page, by virtue of the fact that it runs in a Java web
container, has implicit access to eight very important object types
defined by the Servlet and JSP API, namely: the ServletRequest,
ServletResponse, ServletConfig, ServletContext, HttpSession, JSPWriter,
pageContext, and HttpJspPage object.
Now we?re actually not supposed to access these implicit variables
within our portlet jsps. Remember, with Portlets, we don?t use the
ServletRequest and ServletResponse objects, but instead, we use the
RenderRequest and RenderResponse objects.
The RenderRequest and RenderResponse objects are not implicitly
available to jsp pages that run within a portlet application; however,
the portlet API does provide a special custom tag that indeed makes it
possible to use them. Any Java Server Page that needs easy and implicit
access to classes defined in the portlet API needs only to add a special
custom tag, portlet:defineObjects, to their JSP page. This makes the
RenderRequest, RenderResponse, and even the PortletConfig object
implicitly available with the names renderRequest, renderResponse and
portletConfig.
There are several configuration steps required to use the
<portlet:defineObjects/> custom tag, namely:
1. a reference to the portlet.tld file must be placed in the web.xml
file
2. a taglib directive must be added to the top of the JSP page that uses
the portlet.tld custom tags
3. the <portlet:defineObjects/> custom tag must appear in the
portlet JSP page
Once you have followed these steps, you can implicitly reference the
renderRequest, renderResponse and portletConfig objects within JSP
scriptlets, declarations and expressions.
1: taglib Entry in the web.xml file
To access the various custom tags associated with the portlet API,
including <portlet:defineObjects/>, a reference to the tag library
must be configured in the web.xml file.
<?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>agboPortlets3</display-name>
<welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list>
<taglib id="PortletTLD">
<taglib-uri>http://java.sun.com/portlet</taglib-uri>
<taglib-location>
/WEB-INF/tld/std-portlet.tld
</taglib-location>
</taglib>
</web-app>
2 & 3: Taglib Directive and defineObjects in JSP
After defining the taglib in the web.xml file, you must add a taglib
directive, and the <portlet:defineObjects/> tag to your JSP. After
those elements have been added, you have implicit access to the
renderRequest, renderResponse and the portletConfig variable names.
<%@ page session="false" contentType="text/html"
%>
<%@taglib uri="http://java.sun.com/portlet"
prefix="portlet"%>
<portlet:defineObjects/>
<B>Welcome to this simple JSP<B><BR>
We did some snooping on you.<BR>
This is what we learned about your browser:<I>
<%=renderRequest.getProperty("user-agent")%>
</I><BR>
And we know what language you speak, it's: <I>
<%=renderRequest.getLocale().getDisplayLanguage()%>
</I>Question 3-1
The four lifecycle methods of a portlet are defined in:Which of the
following variable names are made available to JSP files with the
addition of the <portlet:defineObjects/> tag?
¨ a) the Portlet interfaceportletRequest
¨ b) the GenericPortlet interfaceportletResponse
¨ c) the abstract class PortletrenderRequest
¨ d) the abstract class GenericPortletrenderResponse
Question 3-2
During a portlet?s request-response cycle which of the following methods
will be invoked first?To use the portlet custom tags, the taglib-uri
entry must appear in:
a) the portlet.xml file
b) the web.xml file
c) the custom portlet that extends GenericPortlet
d) JSP pagesa) doView
b) doEdit
c) doHelp
d) doDispatch
Question 3-3
The methods doView, doEdit and doHelp correspond to:Which of the
following methods are defined by the PortletRequestDispatcher?
a) Portlet configsforward(String url)
b) Portlet phasesinclude(String url)
c) Portlet statesforward(RenderRequest req, RenderResponse resp)
d) Portlet modesinclude(RenderRequest req, RenderResponse resp)
Question 3-4
A typical JSR-168 portlet will:Compiled portlet source files are stored
in a package aware structure under which folder?
a) extend Portlet interfaceWEB-INF
b) extend GenericPortletMETA-INF
c) extend AbstractPortletWEB-INF\classes
d) extend PortletRendererMETA-INF\classes
Question 3-5
In the MVC paradigm, a JSP is typically considered which MVC component?
a) View
b) Data
c) Controller
d) Model
Answer 3-1
The four lifecycle methods of a portlet are defined in:Which variable
names are made available to JSP files with the addition of the
<portlet:defineObjects/> tag?
¨ a) the Portlet interfaceportletRequest
¨ b) the GenericPortlet interfaceportletResponse
¨ c) the abstract class PortletrenderRequest
¨ d) the abstract class GenericPortletrenderResponse
Options c) and d) are correct.
When you use the defineObjects tag, you can reference the renderRequest
and renderResponse objects within scriptlets and expressions.
Furthermore, these objects provide enough getter methods to allow you to
navigate to just about any object in the Portlet API. It should also be
noted that a third variable, portletConfig, becomes available to a JSP
developer when the defineObjects tag is added to a JSP page.
Answer 3-2
During a portlet?s request-response cycle which of the following methods
will be invoked first?To use the portlet API custom tags, the taglib-uri
entry must appear in which file?
a) portlet.xml
b) web.xml
c) GenericPortlet
d) JSP pagesa) doView
b) doEdit
c) doHelp
d) doDispatch
Option b) is correct.
The tagilb-uri must be defined in the web.xml file, otherwise your JSP
files will not be able to properly resolve the portlet API custom tags.
The JSP pages themselves then need a taglib directive, along with the
<portlet:defineObjects/> tag.
For the most part, we steer clear of the web.xml file when we?re working
in the portlet world. It?s important to take note of the few times we
where do have to finger the deployment descriptor of the web module.
Answer 3-3
The methods doView, doEdit and doHelp correspond to:Which of the
following methods are defined by the PortletRequestDispatcher?
a) Portlet configsforward(String url)
b) Portlet phasesinclude(String url)
c) Portlet statesforward(RenderRequest, RenderResponse)
d) Portlet modesinclude(RenderRequest, RenderResponse)
Option d) is correct.
While the Servlet API?s RequestDispatcher provides both forward and
include methods, only the include method is defined for the
PortletRequestDispatcher.
The String for the url being forwarded to is provided during the call to
getRequestDispatcher(String url).
Answer 3-4
A typical JSR-168 portlet will:Compile portlet source files are stored
in a package aware structure under which folder?
a) extend Portlet interfaceWEB-INF
b) extend GenericPortletMETA-INF
c) extend AbstractPortletWEB-INF\classes
d) extend PortletRendererMETA-INF\classes
Option c) is correct.
All compiled Java code, not to mention property files and resource
bundles, must be places in a package aware subfolder of WEB-INF\classes.
The only file typically found in the META-INF directory is the manifest
file, which should describe the major and minor version number of your
portlet application.
Answer 3-5
In the MVC paradigm, a JSP is typically considered to be which MVC
component?
a) View
b) Data
c) Controller
d) Model
Option a) is correct.
A JSP is typically responsible for generating output to the client,
which represents the view in an MVC, model-view-controller,
architecture.