Level: Intermediate Hongqing Song (song@us.ibm.com), WebSphere Consultant, IBM Richard Scott (rmscott@us.ibm.com), Architect, IBM
01 Jun 2005 See how to enable a JSR 168 portlet on one page to pass information to a JSR 168 portlet on another page, using cross-page wiring. Install and run sample portlets (provided in a download) to see how to enable both static links, which contain pre-defined data, and dynamic input forms, which carry runtime user input, for page-to-page communication between JSR 168 portlets within a single portal. The techniques illustrated and the sample code work with IBM WebSphere Portal V5.1.0.1.
Introduction
In July 2004, we wrote an article, Page-to-page communication between portlets, which showed how to enable communication between IBM API portlets that are on separate pages within a single portal. One of the most frequently asked questions we received from readers is how to enable page-to-page communication between JSR 168 portlets.
JSR 168 is a specification from the Java™ Community Process for portlet development. IBM® WebSphere® Portal V5.0.2.1 provided initial support for the JSR 168 API. With an IBM extension, WebSphere Portal V5.1 supports cooperative portlets for JSR 168 portlets, in which one JSR 168 portlet can communicate with another JSR 168 portlet. With the WebSphere Portal V5.1.0.1 release, you can use cross-page wiring between cooperative portlets for both JSR 168 portlets and IBM API portlets. This article walks through how to enable communication across pages between JSR 168 portlets using this cross-page wiring feature.
You see illustrations of the page-to-page communication techniques using the same QuickSearch example we used in the previous article. This QuickSearch portlet lets you quickly add search functionality to most pages on a portal; then, your users can then easily search the Web site from all pertinent pages. A separate SearchResult portlet displays the results of the quick search functionality on a separate page. Therefore, the two portlets need to communicate across pages.
Introducing the sample scenario
The example scenario used in this article assumes there are two existing JSR 168 portlets:
- QuickSearch portlet provides the ability to search the site. Figure 1 shows the QuickSearch portlet.
- SearchResult portlet displays the results of the search. Figure 2 and Figure 3 show the SearchResult portlet.
QuickSearch supports two ways of searching:
|
Dynamic
|
A user enters search text, clicks Submit, and the SearchResult portlet displays the search result.
| | Static | A user clicks Search resources for WebSphere Portal (a static link which has WebSphere Portal pre-defined as the search text URL parameter), and the SearchResult portlet displays the search result. |
Figure 1. QuickSearch portlet
Figure 2 shows the SearchResult portlet when a user enters the string User input data in the QuickSearch portlet, and then clicks Submit. The SearchResult portlet receives the string, and displays it at the end of the sentence The search text you entered was XXX.
Figure 2. SearchResult portlet with dynamic search
Figure 3 shows the SearchResult portlet when a user clicks the Search resource for WebSphere Portal link in the QuickSearch portlet. The SearchResult portlet receives WebSphere Portal as the URL parameter, and displays it as part of the sentence.
Figure 3. SearchResult portlet with static search
The following products were used to develop and test these sample portlets:
- IBM WebSphere Portal V5.1.0.1
- IBM Rational® Application Developer for WebSphere V6.0, with WebSphere Portal V5.1 test environment
- Microsoft® Internet Explorer V6.0
- Netscape v7.1
- Mozilla Firefox V1.0
All the source code is included in the Download file.
Wiring JSR 168 portlets across pages
In this section, you will see how to implement cross-page wiring for JSR 168 portlets. For detailed information about how to develop cooperative portlets using the JSR 168 API, see Developing JSR 168 compliant cooperative portlets by Amber Roy-Chowdhury and Connie Wu.
Declare exchange capabilities in WSDL files
To enable cross-page wiring for the portlets, you first need to create a Web Services Definition Language (WSDL) file for each portlet in which you declare their exchange capabilities.
Listing 1 shows the QuickSearch portlet WSDL file, which defines a P2PquickSearchAction portlet action. When the action occurs, it outputs a parameter, called p2psample3_search_text, which is the search string. This string is either specified by the user (in the case of a dynamic search), or is predefined in the link (in the case of a static search).
Listing 1. P2PQuickSearch.wsdl (WSDL file for QuickSearch portlet)
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="OrderDetail_Service"
targetNamespace="http://www.ibm.com/wps/p2psample3"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:portlet="http://www.ibm.com/wps/c2a"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.ibm.com/wps/p2psample3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
<xsd:schema targetNamespace="http://www.ibm.com/wps/p2psample3">
<xsd:simpleType name="SearchStringType">
<xsd:restriction base="xsd:string">
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
</types>
<message name="QuickSearchResponse">
<part name="QuickSearch_Text" type="tns:SearchStringType"/>
</message>
<portType name="QuickSearch_Service">
<operation name="Quick_Search">
<output message="tns:QuickSearchResponse"/>
</operation>
</portType>
<binding
name="QuickSearchBinding"
type="tns:QuickSearch_Service">
<portlet:binding/>
<operation name="Quick_Search">
<portlet:action name="P2PQuickSearchAction" type="standard" caption="QuickSearch.action"
description="Get the quick search text"
actionNameParameter="ACTION_NAME"/>
<output>
<portlet:param name="p2psample3_search_text" partname="QuickSearch_Text"
boundTo="request-attribute" caption="QuickSearch.text"/>
</output>
</operation>
</binding>
</definitions>
|
Listing 2 shows the SearchResult portlet WSDL file, which specifies a portlet action, P2PSearchResultAction. When this action occurs, the SearchResult portlet tries to get the p2psample3_search_text input parameter, which can be passed from the QuickSearch portlet by the property broker.
Listing 2. P2PSearchResult.wsdl (WSDL file for SearchResult portlet)
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="OrderDetail_Service"
targetNamespace="http://www.ibm.com/wps/p2psample3"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:portlet="http://www.ibm.com/wps/c2a"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.ibm.com/wps/p2psample3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
<xsd:schema targetNamespace="http://www.ibm.com/wps/p2psample3">
<xsd:simpleType name="SearchStringType">
<xsd:restriction base="xsd:string">
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
</types>
<message name="SearchResultRequest">
<part name="QuickSearch_Text" type="tns:SearchStringType"/>
</message>
<portType name="SearchResult_Service">
<operation name="Search_Result">
<input message="tns:SearchResultRequest"/>
</operation>
</portType>
<binding
name="SearchResultBinding"
type="tns:SearchResult_Service">
<portlet:binding/>
<operation name="Search_Result">
<portlet:action name="P2PSearchResultAction" type="standard" caption="SearchResult.action"
description="Get the search text" actionNameParameter="ACTION_NAME"/>
<input>
<portlet:param name="p2psample3_search_text" partname="QuickSearch_Text" caption="SearchResult.text"/>
</input>
</operation>
</binding>
</definitions>
|
Include the WSDL files in the portlet's WAR file
Next, you need to include the WSDL files in the portlet.xml file, as shown in Listing 3.
Listing 3: Specifying the WSDL files in portlet.xml
<?xml version="1.0" encoding="UTF-8"?>
...
<portlet>
<portlet-name>P2P QuickSearch</portlet-name>
...
<portlet-preferences>
<preference>
<name>com.ibm.portal.propertybroker.wsdllocation</name>
<value>/wsdl/P2PQuickSearch.wsdl</value>
</preference>
</portlet-preferences>
</portlet>
<portlet>
<portlet-name>P2PSearchResult Portlet</portlet-name>
...
<portlet-preferences>
<preference>
<name>com.ibm.portal.propertybroker.wsdllocation</name>
<value>/wsdl/P2PSearchResult.wsdl</value>
</preference>
</portlet-preferences>
</portlet>
</portlet-app>
|
Generate property values from QuickSearch portlet
After you define the P2PquickSearchAction portlet action in the WSDL file, you need to write the code to generate the p2psample3_search_text property value. Listing 4 shows the Java code to process the P2PquickSearchAction.
When the QuickSearch portlet receives this action, it specifies the string as an attribute in the ActionRequest object. This property is delivered to the target portlet (such as SearchResult) by the property broker.
Listing 4. P2PQuickSearchPortlet.java class
public class P2PQuickSearchPortlet extends GenericPortlet
{
...
public static final String FORM_TEXT = "p2psample3_search_text";
public static final String ACTION_NAME_PARAM = "ACTION_NAME";
public static final String P2P_QUICK_SEARCH_ACTION = "P2PQuickSearchAction";
...
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, java.io.IOException
{
String searchText = null;
String actionName = request.getParameter(ACTION_NAME_PARAM);
if(P2P_QUICK_SEARCH_ACTION.equals(actionName))
{
searchText = request.getParameter(FORM_TEXT);
request.setAttribute(FORM_TEXT, searchText);
}
}
...
}
|
Listing 5 shows the JSP code for the QuickSearch portlet. When a user inputs search text and clicks Submit, or when a user clicks the static link, WebSphere Portal generates a P2PQuickSearchAction, and sends the p2psample3_search_text string to the QuickSearch portlet. Then, the property broker delivers the string to the target portlet.
Listing 5. P2PQuickSearchPortletView.jsp
<%
PortletURL actionUrl = renderResponse.createActionURL();
actionUrl.setParameter(P2PQuickSearchPortlet.ACTION_NAME_PARAM,
P2PQuickSearchPortlet.P2P_QUICK_SEARCH_ACTION);
%>
Please enter search text:
<FORM method="POST" action="<%= actionUrl.toString() %>">
<INPUT name="<%=P2PQuickSearchPortlet.FORM_TEXT%>" type="text"/>
<INPUT name="<%=P2PQuickSearchPortlet.FORM_SUBMIT%>" type="submit" value="Submit"/>
</FORM>
<%
actionUrl.setParameter(P2PQuickSearchPortlet.FORM_TEXT, "WebSphere Portal");
%>
<a href="<%=actionUrl.toString() %>">Search resources for WebSphere Portal</a>
|
Receive the property value in the SearchResult portlet
In P2PSearchResult.wsdl, you defined P2PSearchResultAction, which can be used to receive the property delivered by the property broker. When this action occurs, the portlet tries to get the search text from the p2psample3_search_text property, and to process the search.
Listing 6. P2PSearchResultPortlet.java class
public class P2PSearchResultPortlet extends GenericPortlet
{
...
public static final String FORM_TEXT = "p2psample3_search_text";
public static final String ACTION_NAME_PARAM = "ACTION_NAME";
public static final String P2P_QUICK_SEARCH_ACTION = "P2PSearchResultAction";
...
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, java.io.IOException
{
String searchText = null;
String actionName = request.getParameter(ACTION_NAME_PARAM);
P2PSearchResultPortletSessionBean sessionBean = null;
if(P2P__SEARCH_RESULT_ACTION.equals(actionName))
{
searchText = request.getParameter(FORM_TEXT);
sessionBean = getSessionBean(request);
sessionBean.setSearchText(searchText);
}
}
...
}
|
Running the sample portlets
To install and run the sample code:
- Unzip p2p168_code.zip to get the p2psample3.war file.
- Start WebSphere Portal V5.1.0.1 and log in using a portal admin account.
- Install p2psample3.war.
- Create a label called
P2PSAMPLE under My Portal.
- Create two pages called
P2P quick search and P2P search result under P2PSAMPLE.
- Put the
P2P search result portlet on the P2P search result page.
- On the Edit page layout portion of the
P2P search result page, click the Wires tab, and then click Manage Actions?.
- Set the action to Global, as show in Figure 4, to enable cross-page wiring.
Figure 4. Setting up a global action
- Place the
P2P quick search portlet on the P2P quick search page.
- Click the Wires tab, and create a cross-page wire, as shown in Figure 5.
Figure 5. Creating a cross-page wire
- Go to My Portal => P2PSAMPLE and test it. You should see results similar to those shown in Figures 1-3.
Conclusion
WebSphere Portal V5.1.0.1 improves portlet-to-portlet communications by adding the cross-page wiring mechanism. Cross-page wiring is a great way to solve page-to-page communication between portlets for both JSR 168 portlets and IBM API portlets.
The solution for static links with pre-defined data described in our previous article, Page-to-page communication between portlets, is still a valid and simple solution for IBM API portlets. However for page-to-page communication with user input data, cross-page wiring is a better solution than the technique introduced in that article.
In general it is good practice to keep portlets that need to communicate on the same page. Some examples where you might consider page-to-page communication between portlets include the following:
- Strict corporate Web page sizing constraints where there is not enough screen real estate to display the contents of both portlets.
- Too many portlets that are already on a single page.
- Screen flows where you don?t want one Web page looks too busy.
- The example used in this article where you want a quick search available on every page, but for the results to show up on a single page.
Download | Name | Size | Download method |
|---|
| p2p168_code.zip | 11 KB | FTP | HTTP |
Resources
About the authors  | |  | Hongqing Song has been a WebSphere consultant since 2000. He provides WebSphere consulting services across the US. Hongqing Song can be reached at song@us.ibm.com. |
 | |  | Richard Scott is an Architect and Technical Lead in IBM Dallas, eServer Solutions Enablement. He can be reached at rmscott@us.ibm.com. |
Rate this page
|