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
Programming portlets presents the web developer with many new
challenges, not the least of which is figuring out how to invoke a
particular portlet from an html form. A portlet can be placed on a
variety of different web pages at runtime. How can we invoke a
web-based resource when we don?t know the web address of the page on
which it will appear?
Another challenge is making sure that the data submitted through our
form goes to our portlet, and our portlet only. We don?t want other
portlets on the page using data submitted from our form.
Fortunately, the portlet API addresses these very challenges.
The Challenge of Linking Back to a Portlet
When a user clicks the submit button on a form, there must be an
object sitting on the server that is ready to process the user?s
request. With typical Servlet/JSP applications, form submissions are
forwarded to a servlet, and the name of the servlet is specified as
the action of the form; however, we can?t do that with a portlet.
This tutorial looks at the PortletURL object (formerly the PortletURI), and how it can be used
to link back to a portlet running on the portal server, regardless of which page the portlet appear on at runtime.
Please support our site, link to us, buy some books, and remember:
Happy Java!
Rendering a View with Java Server Pages
l Chapter 4Linking Back to the Portal
Forwarding to a JSP to spit out a little ?Hello World? message isn?t
going to win you any Programmer of the Year awards. On the other hand,
using a JSP to generate an html form that helps process input from the
user would be a fastidious application of your programming talents.
Creating Basic HTML Forms for User Input
To grab input from a user, we simply use html forms. For example, if we
wanted the user to guess a magic number between one and ten, we might
provide an html form that looks something like figure 4-1:
Figure 4-1 Using html Forms to obtain User InputWeb based forms are used
to grab input from the user. This form asks a user to enter a number
between one and ten and then click Guess!!.
Using html forms to obtain input from a user is nothing new to a web
developer, but using forms in a portlet environment presents a few
unique and annoying challenges.
The Number Guesser Portlet
For this chapter, we?re going to develop the NumberGuesserPorlet. The
idea is that when the portlet is first viewed, it will ask the user to
guess a magic number between one and ten:
When the user clicks Guess!!!, the NumberGuesserPortlet will check to
see what the number was that the user typed in, and tell the user
whether they guessed the magic number correctly or not. For this
example, we will hard code the magic number to be 5.
The Portlet will then generate a response, telling the user if they
guessed correctly or not:
The response, telling the user if they guessed correctly, will be
generated through print statements in the portlet. The form that takes
input from the user will be implemented as a jsp, creatively named
numberguesser.jsp
The Try Again link will then return the user back to the original
screen, prompting the user to guess the magic number. And remember, all
of this is being performed on a portlet, that could potentially be
sharing screen space with two or twenty other portlets. Furthermore, a
portlet can be placed on any number of different pages in the portal.
This introduces a level of complexity to your portlet applications that
you would never encounter in a typical Servlet and JSP type of
application.
Linking Back to a Portlet
Programming portlets presents the web developer with many new
challenges, not the least of which is figuring out how to invoke a
particular portlet from an html form. A portlet can be placed on a
variety of different web pages at runtime. How can we invoke a web-based
resource when we don?t know the web address of the page on which it will
appear?
Another challenge is making sure that the data submitted through our
form goes to our portlet, and our portlet only. We don?t want other
portlets on the page using data submitted from our form.
Fortunately, the portlet API addresses these very challenges.
The Challenge of Linking Back to a Portlet
When a user clicks the submit button on a form, there must be an object
sitting on the server that is ready to process the user?s request. With
typical Servlet/JSP applications, form submissions are forwarded to a
servlet, and the name of the servlet is specified as the action of the
form; however, we can?t do that with a portlet.
For example, if our number guessing application was implemented as a
servlet, there would be an HttpServlet, perhaps named
NumberGuesserServlet, that would respond to the submission of the form,
and subsequently extract the user?s input. The Servlet would constitute
the action of the form, and the form tag would look like this:
<FORM action = ?NumberGuessServlet?>
But a portlet can?t make a direct call back to itself that easily. The
best a portlet could do is make a call back to the page the portlet is
displayed on, but even that?s impossible to configure in an html form,
because at development time, we don?t know which page, or on how many
pages, our portlet will potentially appear.
Submitting HTML Forms to a Portlet
Notice how the action attribute of the html form element in figure 4-2
points to a question mark. Typically, this would point to a Servlet or a
CGI script that handles the submission of a form. How can we direct the
submission of our form back to our portlet?
Figure 4-2We don?t know the name of the page our portlet may appear on
at runtime. This makes hard coding a target for the action attribute of
the form element impossible. In this case, the action attribute of the
form has been left as a question mark (?).
<FORM action = ??? >I'm thinking of a number between 1 and
10.<BR><BR><I>What is it? </I> <INPUT
type="text" name="number" size="10">
<INPUT type="submit" name="SUBMIT"
value="Guess!!"> </FORM>
The PortletURL Object
Life would be simple if we could tell a form to directly call the
NumberGuesserPortlet, but we can?t. When a request is made to the portal
server, a single portlet can?t be invoked directly. Instead, the user
must request a portal page, and the portal server takes care of
rendering all of the portlets that are part of that page.
So, how do we make a new request to the portal to have our portlet, and
the portal page with which it is associated, re-invoked? The answer is
to have the RenderResponse create a PortletURL object, which essentially
represents a link back to the current portal page, along with all of the
portlets that appear on that page.
response.createRenderURL(); //link back to the portlet
response.createActionURL(); //triggers action phase
The PortletURL Object
?The PortletURL interface represents a URL that reference the portlet
itself.
A PortletURL is created through the RenderResponse. Parameters, a
portlet mode, a window state and a security level can be added to
PortletURL objects. The PortletURL must be converted to a String in
order to embed it into the markup generated by the portlet.
There are two types of PortletURLs:
Action URLs, they are created with RenderResponse.createActionURL, and
trigger an action request followed by a render request.
Render URLs, they are created with RenderResponse.createRenderURL, and
trigger a render request.?
Portlet API JavaDoc,
http://jcp.org/aboutJava/communityprocess/final/jsr168/
Creating the RenderURL Link
To create a link back to a portlet from within an html form, we need to
dynamically generate that action attribute of our form. This can be done
using a JSP expression:
<FORM ACTION = ?<%=renderResponse.createRenderURL()%>? >
Unfortunately, right out of the box, this line of code will not
successfully compile. A little taglib directive, along with a
<portlet:defineObjects/> custom tag must be added to the JSP make
everything kosher.
Required Custom Tags for Portlet Based JSPs
While all JSPs understand that the word response, when used inside of an
expression or a scriptlet, is a reference to the HttpServletResponse
object, a standard JSP has no knowledge of what a portetResponse object
is, even if the reference occurs in a JSP that is part of a portlet
application.
To get the Java compiler to understand that when we say renderResponse
in our JSPs, that we are referring to a subtype of the PortletResponse
object, we need to add two lines to the top of our Java Server Page:
1.<%@taglib uri="http://java.sun.com/portlet"
prefix="portlet"%>
2.<portlet:defineObjects/>
The first line is the taglib, also known as a tag library directive.
This taglib directive indicates that the JSP is going to employ the
services of the portlet custom tag library.
The second line, <portlet:defineObjects/>, is an actual portlet
custom tag in action. The sole purpose of the
<portlet:DefineObjects/> tag is to expose three important portlet
API objects:
The RenderRequest object: renderRequest
The RenderRepsonse object: portletResponse
The PortletConfig object: portletConfig
With local access to the renderRequest, renderResponse, and
portletConfig objects, you have access all othe other important
portlet API components, including the PortletSession, PortletContext,
PortletURL and others.
Figure 4-3 demonstrates how to create a PortletURL object, while
including the taglib directive, and the <portlet:defineObjects/>
custom tag.
Figure 4-3 renderResponse.createRenderURL() To create a link back to the
page a portlet appears on, the createRenderURL() method othe
RenderResponse must be used. Notice the added custom tag and taglib
directive.
<%@page contentType="text/html"%><%@taglib
uri="http://java.sun.com/portlet"
prefix="portlet"%>< portlet:defineObjects /><FORM
action="<%=renderResponse.createRenderURL()%>">I'm
thinking oa number between 1 and 10.<BR><BR><I>What
is it?</I><INPUT name="number" type="text"
size="10" /><INPUT name="submit"
value="Guess!!" type="submit" /></FORM>
Grabbing Form Input From Within a Portlet
With an html form that contains a textfield named ?number?, all we have
to do to figure out what a user typed into that textfield is call the
getParameter method othe request object, and provide the name othe
textfield, in this case ?number?. The input othe user will be returned
to our program as a String.
Again, anything you want to know about the user, which includes what the
user typed into a given textfield, is obtained through the
PortletRequest object, or more specifically during the rendering phase,
the RenderRequest.
With the taglib directive, and the <portlet:defineObjects/> tag,
any expression that uses objects defined in the portlet API will compile
and run successfully, including references to the action attribute oa
form that references the portletResponse and the createRenderURL method.
Coding the NumberGuesserPortlet
The text in figure 4-4 shows the code required to improve our
NumberGuesserPortlet to the point where it can extract form data from
the user. Notice how this portlet acts largely as a controller,
displaying the input form (numberguesser.jsp) ino data has been
submitted, and alternatively, ia number has been submitted, the
portlet provides interactive feedback to the user, namely information on
whether the user correctly guessed the magic number.
Figure 4-4 Code used to grab data from a textfield named number.
package com.examscam.portlet;import java.io.*;import
javax.portlet.*;public class NumberGuesserPortlet extends GenericPortlet
{ protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {/*see ia number is passed to the
server as a parameter*/ String number =
request.getParameter("number"); //ino number was entered,
just show the form i(number == null) { String url =
"/numberguesser.jsp"; getPortletContext()
.getRequestDispatcher(url) .include(request, response); } else { /*ia
number was entered, display the correct answer*/
response.setContentType("text/html"); PrintWriter out =
response.getWriter(); out.print("You guessed " + number);
out.print("<BR>The number was 5");
out.print("<BR>Try again."); /*create a link back to the
portlet using a PortletURL*/ out.print("<A href=\"");
out.print(response.createRenderURL()); out.print("\">Try
Again</A>"); } }}
Data Clashes on the Portal Server
With our funky new code, and the clever use othe PortletURL object,
our NumberGuesserPortlet works pretty darn good; but there is a hidden
little problem buried in the JSP.
Our portlet uses the request.getParameter(?number?) method to figure out
what the user typed into the textfield we named ?number?. But remember,
our Portlet isn?t necessarily the only portlet on the page.
What ianother portlet also uses an html form, with a textfield also
named number? That other portlet would get access to our portlet?s
number, and that isn?t good. Furthermore, our portlet might end up
reading the number from the other portlet, and respond to a submission
with which it had no business interacting. This isn?t a good scenario.
Multiple Portlets and Handling Form Data
Remember, our portlets don?t exist in a vacuum. The page that contains
our NumberGuesserPortlet might also include a StockSellingPortlet that
wants to know the number oshares a user wants to sell. That same page
might also have a SpousalBenefitsPortlet that needs to know the number
owives or husbands a user has. Ieach othose portlets makes a
request.getParameter(?number?) call in their doView method, each one
will get the number that was typed into the form othe
NumberGuesserPortlet.
When a portal page is rendered, the doView method oevery portlet on
the page is invoked, not just that one portlet with which you might
currently be interacting.
Encoding Form Data with getNamespace( )
To ensure that form data being sent from our portlet to the server
doesn?t get confused with the form data oanother portlet, the
RenderResponse object gives us a special method called getNamespace();
this method will return a unique, alpha-numeric character set that
uniquely identifies a portlet on a particular page. Iwe use the
getNamespace() call, and attach that identifying String to each data
element being sent back to the server, no other portlet on the portal
page will mistakenly use our portlet?s data.
All form elements should be encoded using the getNamespace() method of
the response, and all fields being read in a portlet should assume the
field has been namespace encoded.
Note: For simplicity sake, this book will use examples that exclude the
namespace call, which is fine for training, but is completely
unacceptable in development or production. Uniquely identify all oyour
form data, or JavaScripts, by using the getNamespace call to uniquely
encode their names.
***Iyou encode a field in a JSP, make sure you use the same encoding
scheme when retrieving that field on the server, as in the example
below:
Encoding an Attribute in the Form:
<INPUT
name="<%=renderResponse.getNamespace()%>number"/>
Un-Encoding the Same Attribute in the Portlet:
String num = request.getParameter(response.getNamespace( ) +
"number");
Figure 4-5To ensure form data is only sent back to the intended portlet,
the getNamespace method othe RenderResponse object needs to be used.
<%@ page contentType="text/html"%><%@taglib
uri="http://java.sun.com/portlet"
prefix="portlet"%><portlet:defineObjects /><FORM
action="<%=renderResponse.createRenderURL()%>">I'm
thinking oa number between 1 and 10.<BR><BR><I>What
is it?</I><INPUT
name="<%=renderResponse.getNamespace()%>number"/><INPUT
name="submit" type="submit"
value="Guess!!" /></FORM>
***Note: a code change must be made in our Portlet in order to be able
to read the namespace encoded field from the form:
String
number=request.getParameter(response.getNamespace()+"number");
Displaying Images in a Portlet
A similar problem to linking back to a portlet, is figuring out how to
display an image in a portlet. After all, iwe have trouble creating a
URL from our JSP to point back to our original portlet, how do we code a
JSP to link back to a resource, such as a jpg or gifile, in an images
subdirectory oour portlet application?
The solution is to use a special method in the renderRequest called
getContextPath(). This returns a path to the root othe portlet
application. From there, you can map to resources such as image files in
subfolders. So, iyou had an image named wiw.jpg in an images folder
ofthe root othe war, the following code would pull the image out:
renderRequest.getContextPath() + "/images/wiw.jpg";
To display the image in a portlet, you would combine this code with the
standard html IMG tag:
<IMG
src='<%=renderRequest.getContextPath()+"/images/wiw.jpg"
%>'/>
Ultimately though, the resource should also be encoded, so the
getContextPath() method is nested in a call to encode the URL:
<img
src='<%= renderResponse.encodeURL(
renderRequest.getContextPath() +
"/images/wiw.jpg") %>'
/>
The Updated NumberGuesserPortlet
The NumberGuesserPortlet has been updated to demonstrate the changes
that needs to be made in order to read a namespace encoded variable that
is accessed as a parameter through the PortletRequest object.
Figure 4-6 Code used to grab user input from a textfield named ?number?,
taking into account namespace encoded attributes.
package com.examscam.portlet;import java.io.*;import
javax.portlet.*;public class NumberGuesserPortlet extends GenericPortlet
{ protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {/*see ia number is passed to the
server as a parameter/* /*String number =
request.getParameter("number");*/ String number =
request.getParameter(response.getNamespace()+"number"); /*if
no number was entered, just show the form*/ i(number == null) { String
url = "/numberguesser.jsp"; getPortletContext()
.getRequestDispatcher(url) .include(request, response); } else { /*ia
number was entered, tell the user the correct answer*/
response.setContentType("text/html"); PrintWriter out =
response.getWriter(); out.print("You guessed " + number);
out.print("<BR>The number was 5");
out.print("<BR>Try again.");/*create a link back to the
current portlet using a PortletURL*/ out.print("<A
href=\""); out.print(response.createRenderURL());
out.print("\">Try Again</A>"); } }}
A Quick Look at Some Portlet Custom Tags
Since creating render and action URLs, not to mention namespace encoding
form variables, are such common tasks in our JSP files, the Portlet API
provides a couple ohandy-dandy custom tags that make these tasks just
a little bit easier.
Comparatively speaking, it is much slicker to use the
<potlet:renderURL/> custom tag to spit out a link back to the
current portal page, than it is to use the corresponding scriptlet.
With a JSP Expression:
<FORM action=?<%=renderResponse.createRenderURL()%>?>
With a Custom Tag:
<FORM action="<portlet:renderURL/>">
Similarly, using a custom tag to encode a variable name used in a form
is much more readable and maintainable than using a JSP expression.
Additionally, portlet parameters can be attached to a URL with the param
tag:
<portlet:renderURL>
<portlet:param name=?book? value=?portal?/>
</portlet:renderURL>
With a JSP: Expression:
<INPUT
name=?<%=renderResponse.getNamespace()%>number"/>
With a Custom Tag:
<INPUT name="<portlet:namespace/>number"/>
There are five custom tags defined by the portlet tag library descriptor
(tld). They include actionURL, renderURL, param, namespace and
defineObjects.
Our Input Form with Portlet Custom Tags
Figure 4-7Custom tags make Java Server Pages a little easier to write,
and a little easier to read, although some might debate just how much
more readable custom tags make a JSP.
<%@ page contentType="text/html"%><%@taglib
uri="http://java.sun.com/portlet"
prefix="portlet"%><portlet:defineObjects /><FORM
action="<portlet:renderURL/>">I'm thinking oa
number between 1 and 10.<BR><BR><I>What is
it?</I><INPUT name="<portlet:namespace/>number"
type="text" size="10" /><INPUT
name="submit" value="Guess!!"
type="submit" /></FORM>
Figure 4-8 Rendering with Scriptlets vs. Custom TagsWhile portlet custom
tags are used to develop a JSP, the end user has no knowledge othe
behind the scenes implementation.
Deployment Descriptors
With the JSPs coded, and the NumberGuesserPortlet doing what it should,
the last thing our portlet application needs before being zipped up, is
a good portlet.xml file, and web.xml file.
<!--portlet.xml file for the NumberGuesserPortlet application -->
<?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.NumberGuesserPortlet.420453eee0">
<portlet>
<portlet-name>NumberGuesserPortlet</portlet-name>
<display-name>NumberGuesserPortlet</display-name>
<portlet-class>
com.examscam.portlet.NumberGuesserPortlet
</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>NumberGuesserProject</title>
</portlet-info>
</portlet>
</portlet-app>
<-- web.xml file for the NumberGuesserPortlet Project -->
<?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>NumberGuesserProject</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>
Packaging the WAR
Once the manifest file has been created, which simply states
Manifest-Version: 1.1, the NumberGuesserPortlet application can be
zipped up as a war file and deployed to the portal server.
Question 4-1
How would the following legacy Jetspeed Portlet API use othe namespace
tag be migrated over to JSR-168?<input
name="<portletAPI:encodeNamespace value='name'/>">
a) <portlet:namespace/>nameb)
<portlet:namespace>name</portlet:namespace>c)
<portlet:namespace value=?name?/>d) <portlet:namespace
name=?value?/>
Question 4-2
How would the following code, used to display an image in using the
legacy Jetspeed Portlet API, be migrated over to
JSR-168?<%=portletResponse.encoeUrl(?/img/car.jpg?) %>
a) renderRequest.encodeURL(renderResponse.getContextPath() +
?img/car.jpg?)b)
renderResponse.encodeURL(renderRequest.getContextPath() +
?img/car.jpg?)c)
renderRequest.encodeURL(renderResponse.getContextPath() +
?img/car.jpg?)d)
renderResponse.encodeURL(renderRequest.getContextPath() + ?img/car.jpg?)
Question 4-3
Which othe following tags are associated with the JSR-168 API?
¨ a) <portlet:defineObjects/>¨ b) <portlet:actionURL/>¨ c)
<portlet:namespace/>¨ d) <portlet:parameter/>
Question 4-4
What is the correct usage othe <portlet:param/> tag when placed
within a <portlet:actionURL></portlet:actionURL/> tag?
a) <portlet:param name=?id?>007</portlet:param/>b)
<portlet:param>007</portlet:param>c) <portlet:param
name=?id? value=?007?/>d) <portlet:param name=id
value=?007?/>patron</portlet:param/>
Question 4-5
The namespace custom tag uniquely identifies a script or field with:
a) a particular portlet, as defined in the portlet.xml file b) a
specific portlet and portlet window on the current portal pagec) a
specific portlet applicationd) a specific portal page
Question 4-6
Which othe following are non-required attributes othe renderURL and
actionURL custom tags?
¨ a) portletMode¨ b) portletState¨ c) secure¨ d) variable
Question 4-7
The JSR-168 PortletRequestDispatcher allows:
¨ a) Forwarding to a JSP¨ b) Forwarding to a Servlet¨ c) Including the
output oa JSP¨ d) Including the output oa Servlet
Question 4-8
The JSR-168 PortletRequestDispatcher is directly accessed through which
object?
a) PortletContextb) PortalContextc) RenderRequestd)
RenderResponse
Answer 4-1
How would the following IBM Portlet API use othe namespace tag be
migrated over to JSR-168?<input
name="<portletAPI:encodeNamespace value='name'/>">
a) <portlet:namespace/>nameb)
<portlet:namespace>name</portlet:namespace>c)
<portlet:namespace value=?name?/>d) <portlet:namespace
name=?value?/>
Option a) is correct, although it may be a little non-intuitive. The
namespace tag simply prefixes the name othe textfield, so a simple,
single tag sits before the name othe field.
Answer 4-2
How would the following code, used to display an image in using the IBM
Portlet API, be migrated over to
JSR-168?<%=portletResponse.encoeUrl(?/img/car.jpg?) %>
a) renderRequest.encodeURL(renderResponse.getContextPath() +
?img/car.jpg?)b)
renderResponse.encodeURL(renderRequest.getContextPath() +
?img/car.jpg?)c)
renderRequest.encodeURL(renderResponse.getContextPath() +
?img/car.jpg?)d)
renderResponse.encodeURL(renderRequest.getContextPath() + ?img/car.jpg?)
Option d) is correct. To display the image in a JSR-168, you first
obtain the path from the RenderRequest, and then encode the URL using
the renderResponse. Note that the command would work without the
encodeURL, but would not be as programmatically sound.
Answer 4-3
Which othe following tags are associated with the JSR-168 API?
¨ a) <portlet:defineObjects/>¨ b) <portlet:actionURL/>¨ c)
<portlet:namespace/>¨ d) <portlet:parameter/>
Options a) b) and c) are correct. Along with these three tags, the
JSR-168 specification defines a <portlet:param/> tag and
<portlet:renderURL/> tag. Choice d) is incorrect, as the proper
name is <portlet:param/>, not the full name parameter.
Answer 4-4
What is the correct usage othe <portlet:param/> tag when placed
within a <portlet:actionURL></portlet:actionURL/> tag?
a) <portlet:param name=?id?>007</portlet:param/>b)
<portlet:param>007</portlet:param>c) <portlet:param
name=?id? value=?007?/>d) <portlet:param name=id
value=?007?/>patron</portlet:param/>
Option c) is correct. There can be no content within the body othe
<portlet:param/> tag. The information intended to be added as a
parameter to the URL must be defined as name and value attributes othe
tag, not as body content wrapped by the tag.
Answer 4-5
The namespace custom tag uniquely identifies a script or field with:
a) a particular portlet, as defined in the portlet.xml file b) a
specific portlet and portlet window on the current portal pagec) a
specific portlet applicationd) a specific portal page
Option b) is correct. The namespace feature uniquely identifies a script
or field with a particular portlet on a portal page. Ithe same portlet
appears multiple times on a page, each portlet that has its own portlet
window have its own, unique namespace identifier.
Answer 4-6
Which othe following are non-required attributes othe renderURL and
actionURL custom tags?
¨ a) portletMode¨ b) portletState¨ c) secure¨ d) variable
Options a) and c) are correct. The four attributes oa URL custom tag
is portletMode, windowState, secure and var.
Answer 4-7
The JSR-168 PortletRequestDispatcher allows:
a) Forwarding to a JSPb) Forwarding to a Servletc) Including the
output oa JSPd) Including the output oa Servlet
Options c) and d) are correct. The JSR-168 PortletRequestDispatcher does
not allow any forwarding for content generation. Only including content
generated by a web based resource is possible for a
PortletRequestDispatcher, although using a JSP for content generation is
more common than using a Servlet. Answers c) and d) are correct.
Answer 4-8
The JSR-168 PortletRequestDispatcher is directly accessed through which
object?
a) PortletContextb) PortalContextc) RenderRequestd)
RenderResponse
Option a) is the correct answer. The method getRequestDispatcher is
found in the PortletContext.
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.