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
Google

Displaying an Image 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, if we 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 gif file, in an images subdirectory of our portlet application?
The solution is to use a special method in the renderRequest called getContextPath(). This returns a path to the root of the portlet application. From there, you can map to resources such as image files in subfolders

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: ImageDisplay.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 GettingHeadersPortlet


package com.examscam.portlet;

import java.io.*;

import javax.portlet.*;


public class ImageDisplayPortlet extends GenericPortlet {

protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
response.setContentType("text/html");
String url = "/image.jsp";
getPortletContext()
.getRequestDispatcher(url)
.include(request, response);
}


}

The image.jsp



<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" session="false"%>
<portlet:defineObjects />
<P>

<IMG
src='<%= renderResponse.encodeURL(renderRequest.getContextPath() + "/images/wiw.gif") %>'
>



</P>

The 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.ImageDisplayPortlet.5c6eb44df0">
<portlet>
<portlet-name>ImageDisplayPortlet</portlet-name>
<display-name>ImageDisplayPortlet</display-name>
<display-name xml:lang="en">ImageDisplayPortlet</display-name>
<portlet-class>com.examscam.portlet.ImageDisplayPortlet</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.examscam.portlet.nl.ImageDisplayPortletResource</resource-bundle>
<portlet-info>
<title>ImageDisplayPortlet</title>
</portlet-info>
</portlet>
</portlet-app>


The Web Deployment Descriptor (web)


<?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>ImageDisplayPortletProject</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.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>


For the most part, portlets are presentation tier components that react to a web-based, request-response cycle. JSR-168 Portlets are Java based components, and like all Java based components, they can have any number of instance variables defined within them, and they can have any number of business methods as well. However, there is one method that all portlets must define if they want to be rendered on a portal page, and that ever-important method is known as the doView method. The View Mode and the doView Method When a portlet is initially displayed on a page, it is said to be in view mode. The view mode represents the normal way that a portlet looks when it appears on a portal page. The doView method of a portlet corresponds to the view mode of a portlet. The way that a portlet, in its normal mode, should look on a page, is coded into the doView method. Since it must be possible to view a portlet that is placed on a page, every portlet must have a doView method. public void doView (RenderRequest request, RenderResponse response) throws PortletException, IOException The doView method of a portlet is fed the RenderRequest and RenderResponse objects, and also throws the intolerable PortletException and IOException. Along with a concrete implementation of the doView method, to be rendered on a page, a portlet must also define support for the view mode within its deployment descriptors. The PortletRequest Object A portlet?s primary responsibility is to handle a web based request-response cycle. Information about the incoming client request is encapsulated in a PortletRequst object, which is then passed to the pertinent do method of the portlet. The PortletRequest vs. the RenderRequest The JSR-168 specification defines a PortletRequest class, but it is actually a subtype of the PortletRequest that is passed into the doView method of a portlet. This special subtype of PortletRequest is known as the RenderRequest, which sort of makes sense, as the doView method is invoked when a portlet is required to render content to be displayed in the client device. While the doView method of a portlet is passed a RenderRequest, as opposed to the more generic, PortletRequest, the RenderRequest object doesn?t actually define any new methods, so the distinction is largely academic. All of the methods available to the RenderRequest, such as getLocale() and isSecure(), are actually defined in the PortletRequest interface. Inspecting the Incoming Request Any information a developer is allowed to know about the incoming client request is obtained through the request object. Some of the salacious things we can find out about the user through the PortletRequest object include: The preferred language of the user Any headers served up by a client?s browser What a user typed into a textfield Which radio button a user selected The type of browser the client is using he color of the shirt the user is wearing Okay, maybe the PortletRequest can?t tell you the color of the shirt your user is wearing, but it can tell you practically anything else. The PortletRequest makes interrogating your client way too easy. The PortletResponse Object While the PortletRequest is used to discover information about the incoming request, the PortletResponse, or more accurately for methods used during the rendering phase of a portlet, the RenderResponse object, is typically used to send something back, or do something to, the client. For example, to send HTML back to the client, a PrintWriter can obtained from the RenderResponse object through the call response.getWriter(). Other salacious things we can do to with a PortletResponse object include: F Setting the content type for the response F Creating a link back to the current portlet F Obtain a PrintWriter and output content PortletResponse vs. the RenderResponse Only three methods are defined in the PortletResponse interface, namely addProperty, setProperty, and encodeURL. On the other hand, the subtype, the RenderResponse, defines a number of handsome methods, such as createRenderURL, setTitle, setContentType, and of course, getWriter. A Note About Content Creation within a Portlet It should also be noted that only an html snippet is sent back to the client through a do method (doView, doEdit, doConfig, doHelp etc). A portlet should never print out tags. The portal server takes care of the overall page layout through a theme. The job of a portlet is to simply render a snippet of markup language that will be displayed in a predefined segment of the overall portal page. Furthermore, any html tags that are opened in a portlet should be closed in a portlet. Make sure your content snippet is well formed, and doesn?t leave any dangling html tags, such as tag. The PortletResponse and RenderResponse Looking at another Simple Portlet Here?s a simple, yet highly cosmopolitan portlet, that determines a user?s preferred language, and prints out an undiscriminating message. package com.examscam.portlet; import java.io.*; import javax.portlet.*; public class CountrySnooperPortlet extends GenericPortlet { public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { //figure out the user's preferred language String language=request.getLocale().getDisplayLanguage(); //always set the content type before generating output response.setContentType("text/html"); //use the PortletResponse to generate output response.getWriter().print("We love people who speak "); response.getWriter().print(language); response.getWriter().print("!"); } } Figure 2-1 Rendering of the above CountrySnooperPortlet Notice how a method of the PortletRequest, through the RenderRequest, is used to find information about the user?s country of origin. Also notice how the PortletResponse, through the RenderResponse, provides access to a PrintWriter that allows us to send content back to the user. Anything you want to know about the client is in the request, and anything you want to do to the client is done through the response. Packaging Portlets Together If the CountrySnooperPortlet is packaged along with other portlets in the same portlet war file, all of the portlets contained in that war file would be said to be part of the same portlet application. If the CountrySnooperPortlet was packaged along with the HelloWorldPortlet defined earlier, both would be said to be part of the same portlet application, and would could also say that both portlets sharshare a common PortletContext. All portlets defined within a portlet application must be defined in the portlet deployment descriptor, and our CountrySnooperPortlet is no exception. Notice how a few new tags have been added to the portlet definition of the CountrySnooperPortlet. There is a significant amount of meta-data that can be configured in the deployment descriptor, and in this case, we have added a description and a display-name. These are optional tags, but are very useful, both for appropriately internationalizing your portlet, and helping users know the basic use of a portlet when they are deciding to add the given portlet to their portal page. Full portlet.xml File Containing Two Portlets Another Portlet Example: Inspecting Headers Much of the delicious information that comes to the server about the yclient comes in the form of http headers. Headers, which come in as name-value pairs, represent information that a web browser surreptitiously sends to the server on every client request. Using the JSR-168 Portlet API, some creative use of the Enumeration class, and a little Haitian Voodoo sprinkled in for good measure, looping through http headers, and seeing what type of data is being sent to the server, is very easy to do. Here?s a Portlet that uses the getPropertyNames() method of the RenderRequest object to do just that: Figure 2-2 The following portlet loops through the various headers sent to the server, and outputs the corresponding name-value pairs within a portlet. package com.examscam.portlet; import java.io.*;import javax.portlet.*; public class GettingHeadersPortlet extends GenericPortlet { protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.print(" These headers were sent:
"); java.util.Enumeration enum = request.getPropertyNames(); while (enum.hasMoreElements()){ String name = enum.nextElement().toString(); String value = request.getProperty(name); out.print("
"); out.print(name + ": " + value); } } } Debriefing the GettingHeadersPortlet Taking the time to try and understand exactly how the GettingHeadersPortlet works will pay off dividends in the future. Code that loops through an enumeration of named objects and then accesses corresponding values, will come up time and time again, not only in this book, but in day to day portlet and servlet based programming. In figure 2-2, the first line of code in the doView method asks the request object to return all of the various header names in the form of a very flexible collection type called an Enumeration. java.util.Enumeration enum = request.getPropertyNames(); Once we have all of the header names in the enumeration, we can move through the collection of names one at a time, using the hasMoreElements( ) method of the Enumeration class. while (enum.hasMoreElements( )) { //do something } As we loop through the enumeration of header names, we can use the nextElement( ) method of the Enumeration class to grab the current header name. String name = enum.nextElement( ); Once we have the name of the header, we can grab the actual value of the header associated with that name. String value = request.getProperty(name); Of course, if we knew the name of a header of interest, we could name it explicitly. For example, ?user-agent? is the name of a header that tells you information about the type of web browser a client is using. We could grab the value associated with the user-agent header by making the following method call: String browser = request.getProperty(?user-agent?); The above line of code would return the following: (compatible; MSIE 6.0; Windows NT 5.0 ) Headers and other Enumerable Elements The results of our completed, GettingHeadersPortlet, is a portlet that lists all the header names and corresponding values that are sent to a web server from a web based client. The header names include accept, referrer, accept-language, user-agent, host, connection and cache-control. Different browsers and device types will send a different set of headers, so the listing will vary from one client to another. Figure 2-3 shows the values associated with these various header names. Figure 2-3 The rendering of the GettingHeadersPortlet Many objects in both the Servlet and Portlet API return a listing of names as an enumeration, which can be looped through by using code very similar to that that in our GettingHeadersPortlet. Some of those enumerable objects include: F Initialization Strings stored in the PortletContext F Objects placed in the PortletSession F Initialization String stored in the PortletConfig Portlet API Exceptions When coding the doView method of a Portlet, be aware of two potential exceptions that might be thrown. The first exception that might occur is the IOException. A portlet has to deliver content to the portal, and subsequently, to the end user, and if any ports or sockets get messed up along the way, an IOException can potentially be thrown. The other exception the doView method of a portlet might throw is the PortletException. The PortletException is a very general exception, indicating that somehow, the portlet was unable to complete its processing successfully. All of the other exceptions defined in the portlet API use the PortletException as their parent class. These other exceptions include: · PortletModeException · PortletSecurityException · ReadOnlyException · UnavailableException · ValidatorException · WindowStateException Class Diagram for the PortletException Full portlet.xml File For Portlet Application Question 2-1 The four lifecycle methods of a portlet are defined in:Which of the following files can be found in the web-inf folder of a portlet application? ¨ a) the Portlet interfaceapplication.xml ¨ b) the GenericPortlet interfaceweb.xml ¨ c) the abstract class Portletmanifest.mf ¨ d) the abstract class GenericPortletportlet.xml Question 2-2 During a portlet?s request-response cycle which of the following methods will be invoked first?How many methods are defined in the RenderResponse interface? ¡ a) 5 ¡ b) 3 ¡ c) 1 ¡ d) 0¡ a) doView ¡ b) doEdit ¡ c) doHelp ¡ d) doDispatch Question 2-3 The methods doView, doEdit and doHelp correspond to:Which of the following exceptions are explicitly thrown in the method signature of the doView method? ¨ a) Portlet configsNullPointerException ¨ b) Portlet phasesServletException ¨ c) Portlet statesIOException ¨ d) Portlet modesPortletException Question 2-4 A typical JSR-168 portlet will:Which of the following relationships are true? ¡ a) extend Portlet interfacea war file can have many web.xml files ¡ b) extend GenericPortleta war file can contain many portlet.xml files ¡ c) extend AbstractPortleta web.xml file can define many portlets ¡ d) extend PortletRenderera portlet.xml file can define many portlets Answer 2-1 The four lifecycle methods of a portlet are defined in:Which of the following files can be found in the web-inf folder of a portlet application? ¡ a) the Portlet interfaceapplication.xml ¡ b) the GenericPortlet interfaceweb.xml ¡ c) the abstract class Portletmanifest.mf ¡ d) the abstract class GenericPortletportlet.xml Options b) and d) are correct. All portlet war files must contain a web.xml file, and a portlet.xml file. The application.xml file is found in the root of an Enterprise Application Archive (EAR), and the manifest file is found in the META-INF folder, not the web-inf folder. Answer 2-2 During a portlet?s request-response cycle which of the following methods will be invoked first?How many methods are defined in the RenderResponse interface? ¡ a) 5 ¡ b) 3 ¡ c) 1 ¡ d) 0¡ a) doView ¡ b) doEdit ¡ c) doHelp ¡ d) doDispatch Option d) is correct. Curiously, the RenderResponse defines no new methods, and can be considered a marker interface. All of the methods that can be called on the RenderResponse object are defined in the parent type, PortletResponse. Comparatively, the RenderRequest defines only three of its own methods, inheriting the rest from PortletResponse. Answer 2-3 The methods doView, doEdit and doHelp correspond to:Which of the following exceptions are explicitly thrown in the method signature of the doView method? ¨ a) Portlet configsNullPointerException ¨ b) Portlet phasesServletException ¨ c) Portlet statesIOException ¨ d) Portlet modesPortletException Options c) and d) are correct. All of the do methods throw both the IOException, and the PortletException. Servlets throw the ServletException, and while a portlet can indeed throw a NullPointerException, the null pointer is an unchecked exception, and need not be listed in the throws clause. Answer 2-4 A typical JSR-168 portlet will:Which of the following relationships are true? ¡ a) extend Portlet interfacea war file can have many web.xml files ¡ b) extend GenericPortleta war file can contain many portlet.xml files ¡ c) extend AbstractPortleta web.xml file can define many portlets ¡ d) extend PortletRenderera portlet.xml file can define many portlets Only option d) is correct. A war file can have only one web.xml file, and only one portlet.xml file. Portlets are not defined in the web.xml file with JSR-168. However, a portlet.xml file can define many portlets. It is many portlets working together that makes up a commonly packaged, portlet application.
Google



eXTReMe Tracker

ActionRequest ActionResponse GenericPortlet PortletRequestDispatcher . Portlet ..... PortletURL
PortletContext PortletException PortletMode a PortletModeException PortletPreferences
PortalContext PortletResponse PortletSession PortletSecurityException PreferencesValidator
PortletConfig RenderRequest RenderResponse UnavailableException PortletSessionUtil
PortletRequest ValidatorException WindowState WindowStateException UnmodifiableException