Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Page-to-page communication between legacy Web pages and portlets

Hongqing Song (song@us.ibm.com), WebSphere Consultant, IBM
Hongqing Song has been a WebSphere consultant since 2000. He provides WebSphere consulting services across the nation. He works in IBM Austin in eServer Solutions Enablement.
Richard Scott (rmscott@us.ibm.com), Architect, eServer Solutions Enablement, IBM Dallas
Richard Scott is an Architect and Technical Lead in IBM Dallas, eServer Solutions Enablement.

Summary:  This article describes two approaches for passing information from legacy Web pages to portlets. The receiving portlet could be either a JSR 168 portlet or an IBM API portlet. It includes sample code for both scenarios in a download, which you can install and deploy. The samples illustrate the use of a static link, which contains pre-defined data, and a dynamic field, which carries runtime user input. The solution for IBM API portlets works in both IBM WebSphere Portal V5.0.X and V5.1.X. The solution for JSR portlets works in WebSphere Portal V5.1.x only.

Date:  17 Aug 2005
Level:  Intermediate

Activity:  7119 views
Comments:  

Introduction

IBM® WebSphere® Portal V5.1.0.1 introduced cross-page wiring as an approach for page-to-page communication between JSR 168 portlets and between IBM API portlets. However, readers of our earlier articles (see Resources), as well as the requirements of several of our current projects, indicate there is another kind of page-to-page communication that needs to be addressed: that is, communication between legacy Web pages (pages that do not run under a portal server) and portlets on a portal page. A legacy Web page could be in a variety of formats, including static HTML, CGI, ASP, or JSP and Servlet.

Because the IBM API portlet is a subclass of the Servlet class, it can access HTTP parameters (that is, URL parameters and data submitted from an HTML form) directly. However, JSR 168 portlets only mimic the Servlet API, and they cannot access HTTP parameters directly. Therefore, the solutions for IBM API portlets and JSR 168 portlets are different.

This article is for architects and developers who are need to integrate legacy Web applications and WebSphere Portal applications. Readers should have basic experience in portlet development and Web application development. For an overview of developing portlets, see IBM Rational Application Developer V6 Portlet Application Development and Portal Tools (see Resources).


Introducing the scenarios

In our two earlier articles, Page-to-page communication between portlets and Page-to-page communication between JSR 168 portlets in WebSphere Portal V5.1.0.1, we used a "Quick search" sample to illustrate the proposed solutions for those scenarios. This article uses the same example to illustrate our solution to a legacy Web page to portlet communication scenario.

WebSphere Portal is a new Web technology, and many companies may already have existing legacy Web applications. It takes time, resources, and money to convert legacy Web applications into WebSphere Portal applications. Therefore, many WebSphere Portal applications need to coexist and integrate with legacy Web applications. These two kinds of applications could be running in the same or different server environments. The solution introduced in this article works in both situations.

Suppose a company created a nice search engine using WebSphere Portal, and the company wants its legacy Web sites pages to take advantage of this new search engine. In order to provide that capability, you would need to enable page-to-page communication between the existing legacy Web pages and the portlets in the company portal.

Figure 1 shows the QuickSearch page on the legacy site. It can be a standalone page, or a utility section on a page on the legacy site.

DynamicA user enters search text, clicks the Submit button, and the SearchResult portlet displays the search result.
StaticA 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 page on legacy Web site
XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width.

Figure 2 shows the SearchResult portlet after a user enters the string User input data on the QuickSearch legacy page, and then clicks the Submit button. 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
XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width.

Figure 3 shows the SearchResult portlet after a user clicks the Search resources for WebSphere Portal link on the QuickSearch legacy page. 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
XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width.

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 p2p_legacy_code.zip.


Scenario 1. IBM API portlets

Because an IBM API portlet is a subclass of Servlet, it can access HTTP parameters directly. So you could implement the communication between legacy Web pages and IBM API portlets using URL Mapping and HTTP parameters.

Listing 1 shows the HTML source code for the QuickSearch Web page that communicates with the SearchResult portlet implemented using IBM API, in this scenario. The URL of the portal page that contains the SearchResult portlet is

http://localhost:9081/wps/portal/search_result

where search_result is the URL Mapping name of the SearchResult portal page.

There are two reasons to create a URL Mapping name for the page:

  1. It is much more user friendly than the default URL generated by WebSphere Portal. The default URL is hard to read and it is machine-dependent (different machines generate different URLs for the same page). The following URL is an example of the WebSphere Portal generated URL for the search result page:
    http://localhost:9081/wps/portal/!ut/p/kcxml/04_Sj9SPykssy0xPLMnMz0vM0Y_QjzK
    LN4g3cQHJgFiWQBaYdoWJGJtCRBBqHOECvh75uan63voB-gW5oaER5Y6KAIhg
    H-A!/delta/base64xml/L3dJdyEvUUd3QndNQSEvNElVRS82XzBfOUQ!

  2. It is easier to move the portal application from the staging server to the production server, because you can have the same URL Mapping name for a page on different servers. You would not have that control with the URL generated by WebSphere Portal.

See the WebSphere Portal Information Center (reference in Resources) to learn how to create the URL mapping. After creating a URL mapping, you can use URL http://localhost:9081/wps/portal/search_result to point to the page.

In Listing 1, you see that the data p2psampel5_search_text will be submitted as HTTP parameters to the portal page.


Listing 1. p2p_ibm_portlet.html (source code of QuickSearch Web page to communicate with the IBM API portlet).

<html>
<title>Quick search</title>
<body>
<form method="get" action="http://localhost:9081/wps/portal/search_result">
<table>
	<tr><td colspan="2">Please enter search text</td></tr>
	<tr>
	<td><input type="text" name="p2psample5_search_text"/></td>
	<td><input type="Submit" value="Submit"/></td
	</tr>
</table>
</form>
<a href="http://localhost:9081/wps/portal/search_result?p2psample5_search_text=WebSphere%20Portal">
Search resources for WebSphere Portal
</a>
</body>
</html>

Listing 2 shows a snippet of the source code for the SearchResult portlet, which is an IBM API portlet. The portlet retrieves HTTP parameters submitted from the legacy page directly.


Listing 2. doView() method of SearchResultPortlet.

public void doView(PortletRequest request, PortletResponse response) 
  throws PortletException, IOException 
{
	...
	// Retrieves the URL parameter submitted from the legacy Web page.
	String p2psample5_search_text = request.getParameter("p2psample5_search_text");
	
       // Make a view mode bean
	SearchResultPortletViewBean viewBean = new SearchResultPortletViewBean();
	viewBean.setSearchText(p2psample5_search_text);
	request.setAttribute(VIEW_BEAN, viewBean);
 		
      // Invoke the JSP to render        		
      getPortletConfig().getContext().include(VIEW_JSP, request, response);
	...
}

To deploy the sample code for this scenario:

  1. Download and unzip p2p_legacy_code.zip.
  2. Put p2p_ibm_portlet.html on the Web server. If IBM HTTP server is used, put the file in directory: {$httpServer_home}/htdocs/en_US/p2p where {$httpServe_home} is the installation directory of the IBM HTTP server.
  3. Start WebSphere Portal.
  4. Install P2PSample5.war.
  5. Under My Portal, create a label called Search result.
  6. Under Search result, create a page called P2PSample.
  7. Add the SearchResult portlet on the Search result page.
  8. Create a URL Mapping called "search_result", and map it to My portal-->Search result-->P2PSample.
  9. Make the Search result page public, or enable the security of WebSphere Portal. (Refer to WebSphere Portal Information Center ).
  10. If the search result page is secure, and WebSphere Portal security is not enabled, the sample won’t work. By default, when WebSphere Portal 5.X is installed, security is not enabled.
  11. To tst the sample, open a browser with this URL: http://localhost/p2p/p2p_ibm_portlet.html
  12. Click the Search resources for WebSphere Portal link, or enter some search text and click the Submit button.
    If the search result page is public, you see it directly. However, if the search result page is secure and WebSphere portal security is enabled, you are challenged to enter your user name and password; then you see the search result page with the data submitted from the legacy Web page.

Scenario 2: JSR 168 portlets

Because a JSR portlet only mimics the Servlet API, it cannot access HTTP parameters directly. So the solution above will not work for JSR 168 portlets. However, WebSphere Portal V5.1 has built-in classes, the WebSphere Portal System Programming Interface (SPI), which enable developers to create a URL that points to a portal page and to pass data to JSR portlets on that page. See Resources for access to the SPI Javadoc.

Important: There is a limit of 2048 characters for the total URL length.

Figure 1 shows our solution for JSR 168 portlets. The process is as follows.

  1. A user enters search text and clicks Submit. Alternatively, the user just clicks the static link on the QuickSearch page. Either way, the data is sent as HTTP parameters to P2PHandler.
  2. P2PHandler gets the HTTP parameters sent from the Web page. It passes these parameters to Java™ classes in P2pUtil.jar, which is created using the Model SPI.
  3. The Java classes in P2PUtil.jar create the URL that points to the SearchResult portal page. Parameters sent from the legacy Web page are included as render parameters in the URL.
  4. P2PHandler gets the URL and redirects to the SearchResult portal page. The SearchResult portlet retrieves the render parameters, and performs the search.

Figure 4: Component diagram for scenario 2
Figure 4: Component diagram for scenario 2

Listing 3 shows the HTML source code for QuickSearch legacy page. In this scenario, the QuickSearch page points to p2pHandler.jsp.


Listing 3. p2p_168_portlet.html (source code of QuickSearch legacy page)

<html>
<title>Quick search</title>
<body>
<form method="get" action="http://localhost:9081/wps/p2p/p2pHandler.jsp">
<table>
	<tr><td colspan="2">Please enter search text</td></tr>
	<tr>
	<td><input type="text" name="p2psample4_search_text"/></td>
	<td><input type="Submit" value="Submit"/></td
	</tr>
</table>
</form>
<a href="http://localhost:9081/wps/p2p/p2pHandler.jsp?p2psample4_search_text=
WebSphere%20Portal">
	Search resources for WebSphere Portal
</a>
</body>
</html>

P2PHandler, as shown in Listing 4, is implemented using JSP. It retrieves the HTTP parameters, calls Java classes in P2PUtil.jar to build the URL, and then redirects to the SearchResult portal page.


Listing 4. p2pHandler.jsp

<%@ page import="p2phandler.util.P2PURLGenerator"%>
<%
// Retrieve HTTP parameter sent from legacy Web page.
String searchStr = request.getParameter("p2psample4_search_text");
try
{
  // Call classes in P2PUtil.jar to create the URL. 
  // Parameters sent from the legacy Web page are included in the URL.
  String targetURLStr = P2PURLGenerator.generateURLString(
   "p2psample.SearchResult","p2psample4.win.SearchResult", 
   "p2psample4_search_text", searchStr);	
  // Redirect to the SearchResult page
  response.sendRedirect(targetURLStr);
  }
   catch(Exception e)
  {
   System.err.println(e.toString());
  }
%>

Listing 5 shows how to generate the URL with render parameters using the WebSphere Portal SPI classes:


Listing 5. P2PURLGenerator.java class

public class P2PURLGenerator 
{
     ...
    public static String generateURLString(
	String pageName,   // Custom unique name of the page containing the portlet
       String portletName, // The unique name of the portlet window 
	String paramName,  // The parameter name
       String paramValue  // The parameter value
       )   throws StateException, NamingException, IOException 
   {

    final StateManager mgr = getStateManager();

    // Get the URL factory
final URLAccessorFactory URLFactory = 
(URLAccessorFactory) mgr.getAccessorFactory(URLAccessorFactory.class);

    // Request a URL
    // The 3rd argument specifies whether the URL points to the
    //    protected (authenticated) area
    // Pass in "false" if your page is accessible for unauthenticated users
    final EngineURL URL = URLFactory.newURL(new MyServerContext(), false, true, 
    mgr.newState(), Constants.EMPTY_COPY);

    // Set the page this URL should point to
    final SelectionAccessorFactory selectionFactory = 
    (SelectionAccessorFactory) mgr.getAccessorFactory(SelectionAccessorFactory.class);
    // Request the selection controller to set the page; 
    //   pass in the state associated with the created URL
    final SelectionAccessorController selectionCtrl = 
    selectionFactory.getSelectionController(URL.getState());
    // Set the page; you need the unique name (String) or the ObjectID of that page
    selectionCtrl.setSelection(pageName);
    // Dispose the accessor (avoids memory leak)
    selectionCtrl.dispose();

    // Set portlet render parameters
    final PortletAccessorFactory portletAccessorFactory = 
    (PortletAccessorFactory) mgr.getAccessorFactory(PortletAccessorFactory.class);
    //Get the portlet controller to set render parameters; 
    //  pass in the state associated with rge created URL
    final PortletAccessorController portletCtrl = 
    portletAccessorFactory.getPortletController(portletName, URL.getState());
    // Get the modifiable render parameter map
    final Map parameters = portletCtrl.getParameters();
    // Set the render parameter
    parameters.put(paramName, new String[]{paramValue});
    // Dispose the accessor (avoids memory leak)
    portletCtrl.dispose();

    // Now convert the URL to a String; pass in your writer.
    // writeDispose() writes the URL to the given writer and 
    //   disposes of the URL afterwards.
    // If you want to display this URL a multiple times pls use writeCopy().
    return URL.writeDispose(new StringWriter()).toString();
  }
 ...
}

The code above shows that you need to know two things in order to enable one JSR portlet to communicate with another JSR portlet in a different page:

  • The unique name of the target portal page.
  • The unique name of the portlet window on that page.

Although it is possible to define the unique name of a portal page in the WebSphere Portal administration console, you cannot define the unique name of a portlet window. You need to write an XML deployment file, and create these unique names using the xmlaccess utility.

Listing 6 shows part of the p2p_create_page.xml file (in p2p_legacy_code.zip), which creates a portal page titled Search result with the unique name of p2psample.SearchResult, and puts the SearchResult portlet, with a unique name of p2psample4.win.SearchResult, on the page.


Listing 6. p2p_create_page.xml

...
 <content-node action="locate" objectid=
    "Content.Root.My_Portal" uniquename="wps.My Portal"/>          
 <content-node content-parentref="Content.Root.My_Portal" action=
   "update" active="true" objectid="SearchResult.page" uniquename=
     "p2psample.SearchResult" type="page" skinref="undefined">
    <supported-markup markup="html" update="set"/>
    <localedata locale="en">
      <title>Search result</title>
    </localedata>
    <component action="update" ordinal="100" 
          type="container" orientation="H">
      <component action="update" ordinal="100"
           type="container" orientation="V" >
      <component action="update" ordinal="100" 
           type="control" uniquename="p2psample4.win.SearchResult">       
      <portletinstance action="update" objectid="SearchResult.page.portlet1" 
           Portletref="p2p.portlet.SearchResult"/>  
      </component>
      </component>
    </component>
  </content-node>
...

Listing 7 shows source code for SearchResult portlet, which is a JSR 168 portlet. It retrieves the render parameters from the URL that is built using URLGenerator class.


Listing 7. SearchResultPortlet.java

public class SearchResultPortlet extends GenericPortlet 
{
...
  public void doView(RenderRequest request, RenderResponse response) 
       throws PortletException, IOException 
  {
      	// Retrieve the HTTP parameter sent from the legacy Web page.
	String p2psample4_search_text = 
	    request.getParameter("p2psample4_search_text");
	SearchResultPortletViewBean viewBean=new SearchResultPortletViewBean();
	viewBean.setSearchText(p2psample4_search_text);
	request.setAttribute(VIEW_BEAN, viewBean);
	// Set the MIME type for the render response
	response.setContentType(request.getResponseContentType());

	// Invoke the JSP to render
	PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(
       getJspFilePath(request, VIEW_JSP));
	rd.include(request,response);
    }
…
}

To deploy the sample code for scenario 2:

  1. Unzip the p2p_legacy_code.zip file.
  2. Copy p2p_168_portlet.html onto the Web server. If you use IBM HTTP server, place the file into the directory:
     {$httpServer_home}/htdocs/en_US/p2p
     

    where {$httpServe_home} is the installation directory of the IBM HTTP server.
  3. Copy p2pHandler.jsp to directory:
    {$was_home}/installedApps/machine_name/wps.ear/wps.war/p2p
     

  4. Place P2PUtil.jar into:
     ${wps_home}/shared/app  

    where ${wps_home} means WebSphere Portal installation directory.
  5. Place P2PSample4.war into the ${wps_home}/installableApps directory.
  6. In ${wps_home}/bin, create a directory called xmlaccess. Then, copy p2p_create_page.xml to ${wps_home}/bin/xmlaccess.
  7. Start WebSphere Portal.
  8. Open a command prompt, go to ${wps_home}/bin/xmlaccess, and run the following command (on one line):
    ..\xmlaccess.bat –in p2p_create_page.xml –out result.xml –user 
       wpsadmin –pwd password –URL http://localhost:9081/wps/config
    

    Use the user name and password that works for your WebSphere Portal server.
  9. Stop WebSphere portal and start WebSphere Portal.
  10. Make a page called Search result under My portal public.
  11. To test the sample, open the following URL in a Web browser:
    http://localhost/p2p/p2p_168_portlet.html	
    

  12. Click the Search resources for WebSphere Portal link, or enter some search text and click Submit. You see the search result page with the data submitted from the legacy QuickSearch Web page.

Conclusion

You can enable communication to portlets from legacy Web pages using the solutions provided in this article. You saw how to use URL Mapping and HTTP parameters for page-to-page communication between legacy Web pages and IBM API portlets. For JSR 168 portlets, we used HTTP Parameters processed using the Model SPI provided by WebSphere Portal V5.1.X . In addition, for JSR 168 portlets, you can use xmlaccess to create the unique name of the target portal page and the unique name of the portlet window on that page. To communicate from a portlet to a legacy Web page, you can simply send the data using the HTTP parameters with the GET or POST method.



Download

DescriptionNameSizeDownload method
Code samplesp2p_legacy_code.zip17 KBFTP|HTTP

Information about download methods


Resources

Learn

Get products and technologies

About the authors

Hongqing Song

Hongqing Song has been a WebSphere consultant since 2000. He provides WebSphere consulting services across the nation. He works in IBM Austin in eServer Solutions Enablement.

Richard Scott

Richard Scott is an Architect and Technical Lead in IBM Dallas, eServer Solutions Enablement.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Rational
ArticleID=92009
ArticleTitle=Page-to-page communication between legacy Web pages and portlets
publish-date=08172005