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

Portlets and JSPs

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 {

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

}

The welcome.jsp File

<%@ 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>

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.JSPDisplayPortlet.2221041df0">
<portlet>
<portlet-name>JSPDisplay</portlet-name>
<display-name>JSPDisplay</display-name>
<display-name xml:lang="en">JSPDisplay</display-name>
<portlet-class>com.examscam.portlet.JSPDisplayPortlet</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.JSPDisplayPortletResource</resource-bundle>
<portlet-info>
<title>JSPDisplay</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>JSPDisplay</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>
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.
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