.NET Development & the IBM WebSphere Portal Server

Shelly presents techniques and examines tools for developing .NET applications for IBM's WebSphere Portal Server.


September 04, 2008
URL:http://www.drdobbs.com/web-development/net-development-the-ibm-websphere-porta/210500054

Shelly has worked in software development for 18 years and is a freelance software consultant. She can be contacted at [email protected].


Business users like web portals because portal views let them work with corporate data and business processes through a single, consistent UI. Software development teams like them because portals provide a comprehensive UI framework and the architectural opportunity to integrate applications in real-time at the front-end, rather than via potentially costly and unreliable offline batch processes at the back-end. Consequently, portals are increasingly considered an essential part of an enterprise SOA strategy. .NET developers, however, have had limited options when it comes to portals, since most high-end portals—BEA's WebLogic Portal Server and IBM's WebSphere Portal Server come to mind—are based on Java EE. In this article, I present techniques and examine tools for developing .NET applications for IBM's WebSphere Portal Server.

JSR 168

The major portlet specification is JSR 168 (jcp.org/ en/jsr/detail?id=168), which ensures that portlets developed in Java can run on multiple portal servers. Many commercial and open-source organizations have adopted this standard, which defines the programming model for portlets and the contract between the portlets and the portlet container.

[Click image to view at full size]

Figure 1: Portlet lifecycle.

The portlet lifecycle (Figure 1) consists of two main phases:

The portlets are defined as a standard portlet descriptor file, portlet.xml; see Listing One. Within JSR 168 is consistent support for persistent and transient data management. Portlets can access two different types of persistent data:

$?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">
<portlet>
    <description>This is a test portlet</description>
    <portlet-name>A test portlet</portlet-name>
    <display-name>A Test Portlet</display-name>
    <portlet-class>GhDynamicPortlet</portlet-class>
    <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>VIEW</portlet-mode>
    </supports>
    <portlet-info>
        <title>Test Portlet</title>
        <short-title>Test</short-title>
        <keywords>Test</keywords>
    </portlet-info>
</portlet>
</portlet-app>
Listing One

<portlet-preferences>      
    <preference>         
        <name>userData</name> 
        <value></value>      
    </preference>      
</portlet-preferences>
Listing Two

Transient data comes from two sources:

Mainsoft for Java EE, Portal Edition

Within Mainsoft for Java EE, Portal Edition (www.mainsoft.com), the JSR 168 API is reproduced in the .NET namespace javax.portlet, mirroring the Java portlet-api.jar. .NET developers have full access to the entire API. The vmw.PortletUtils class lets you access the request and response objects; see Listing Three.

From these objects, you can access the entire functionality of the JSR 168 spec. Listing Four shows how portlet preferences can be stored, while Listing Five shows how the portlet can be read back—a useful technique for preserving data across user sessions.

Mainsoft for Java EE, Portal Edition provides a set of ASP.NET controls that automatically apply the WebSphere Portal styles to the controls. However, ASP.NET developers can use any of the standard controls (if desired). These pick up the WebSphere theme and skin if you use the correct portal styles.

ActionRequest ar = vmw.portlet.PortletUtils.getPortletRequest() as ActionRequest;
RenderResponse rs = vmw.portlet.PortletUtils.getPortletResponse() as RenderResponse;
Listing Three

ActionRequest ar = vmw.portlet.PortletUtils.getPortletRequest() as ActionRequest;
PortletPreferences prefs = ar.getPreferences();         
prefs.setValue("userData", someData);         
prefs.store();
Listing Four

RenderRequest rr = vmw.portlet.PortletUtils.getPortletRequest() as RenderRequest;
PortletPreferences prefs = rr.getPreferences();
string userData = prefs.getValue("lastsearch", string.Empty);
Listing Five

Once the code is ready for compilation, the tool automatically converts the MSIL to Java bytecode, creates a standard WAR file, and deploys it to the WebSphere Portal. You can debug code directly in Visual Studio as long as the Portal debugging service is turned on.

Sample JSR 168 Application in ASP.NET

One benefit of portals is the ability to perform integration at the UI layer, letting a portal page update multiple back-end systems simultaneously. To enable this, it is essential that portlets share data. WebSphere inter-portlet communication is facilitated by a broker that lets portlets exchange similarly typed properties. Essentially, the source portlet must define a WSDL file that specifies an output message (see Listing Six), while target portlets must define a WSDL file that specifies the related input message format (Listing Seven).

The WSDL files are fairly standard except within the operation node. Referring to Listing Six, you must define a named action and named parameter of the ActionRequest to which you attach your data as a named attribute. Within your .NET code, the data is applied to the attribute (Listing Eight).

<types>
  <xsd:schema targetNamespace="http://www.ibm.com/wps/search">
    <xsd:simpleType name="SearchType"><xsd:restriction base="xsd:string"></xsd:restriction></xsd:simpleType>
  </xsd:schema>
</types>
<message name="Search"><part name="Text" type="tns:SearchType"/></message>
<portType name="Service"><output message="tns:Search"/></operation></portType>
<binding name="Binding" type="tns:Service">
  <portlet:binding/>
  <operation name="Search">
    <portlet:action name="Action" type="standard" caption="action" description="Search text"
    actionNameParameter="ACTION_NAME"/>
    <output><portlet:param name="demo_text" partname="Text" boundTo="request-attribute" caption="text"/></output>
  </operation>
</binding>
Listing Six

<types>
  <xsd:schema targetNamespace="http://www.ibm.com/wps/search">
    <xsd:simpleType name="SearchType"><xsd:restriction base="xsd:string"></xsd:restriction></xsd:simpleType>
    </xsd:schema>
</types>
<message name="Search"><part name="Text" type="tns:SearchType"/></message>
<portType name="Service"><operation name="Result"><input message="tns:Search"/></operation></portType>
<binding name="Binding" type="tns:Service">
  <portlet:binding/>
  <operation name="Result">
    <portlet:action name="Action" type="standard" caption="action" description="Search text"
    actionNameParameter="ACTION_NAME"/>
    <input><portlet:param name="demo_text" partname="Text" caption="text"/></input>
  </operation>
</binding>
Listing Seven

PortletRequest pr = vmw.portlet.PortletUtils.getPortletRequest();
ActionRequest ar = pr as ActionRequest;
if (ar != null)
{
    string actionName = ar.getParameter("ACTION_NAME");
    if (actionName == "Action")
    {
        ar.setAttribute("demo_text", data);
    }
}
Listing Eight

The target portlet reads the data back from the ActionRequest (Listing Nine). The sample application demonstrates how to write two portlets that cooperate. The first portlet provides a search text box and a submit button (Search.aspx). Once clicked, the portlet loads a new page (SearchResults.aspx) with a DataGrid displaying the result of the search. In a real-world application, this would probably involve a web service call or database look-up; however, for simplicity the sample code simply loads some XML from a file of test data. Initially, the second portlet is empty, but when the user selects a row in the DataGrid, a number of values from the selected row are broadcast via the property broker and displayed in the page LinkedData.aspx. If the second portlet interrogates another database using this data, you have a simple method of integrating two systems at the UI layer.

ActionRequest ar = vmw.portlet.PortletUtils.getPortletRequest() as ActionRequest;
if (ar != null)
{
    string actionName = ar.getParameter("ACTION_NAME");
    if (actionName == "Action")
    {
        string demoText = ar.getParameter("demo_text").ToString();
    }   
}
Listing Nine

Once the portlets are deployed, they must be "wired" up. This process is an administrative task that defines to the WebSphere property broker the particular output message that the source portlet data is to send to the target portlet. The wiring tool is described in the WebSphere Portal documentation.

To run the sample, you need Visual Studio 2003 and a copy of Mainsoft for Java EE, Portal Edition (trial versions are available). The sample app (available online at www.ddj.com/code/) includes a Visual Studio.NET Java EE Portal project consisting of two simple portlets demonstrating inter-portlet communication as described in this article.

WSRP

An emerging standard for portlet development is Web Services for Remote Portlets (WSRP; www.oasis-open.org). WSRP defines a set of SOAP messages that contain portlet mark-up fragments. This means that the portlets themselves can be hosted on a remote machine to the portal server. The technology used to develop the portlets is immaterial so long as the HTML is exposed by a WSRP-compliant web service—a "WSRP Producer." The portal acts as a WSRP Consumer. WSRP 1.0 supports content navigation and interactions between the user and the portlet, managed by the portal. Future versions of WSRP will also support inter-portlet communication between remote portlets, mediated by the portal.

NetUnity (www.netunitysoftware.com) offers a tool that exposes ASP.NET pages as WSRP portlets via a simple mechanism. The tool adds a new PortletLibrary template to the Visual Studio IDE that offers two new types of file: a Portlet and a WSRP Portlet Page. The Portlet is a simple file that defines the ASP.NET pages that provide the entry points for the portlet in its standard modes: View, Edit, and Help (Listing Ten). The Portlet file has parallels with the portlet.xml file of JSR 168.

using System;
using System.Web.UI;
using NetUnity.WSRP;
using NetUnity.WSRP.ASP;

[OfferedHandle("800b284e-dc02-4c29-961a-a289149a979e")]
[Title("My ASP.NET Portlet")]
[DisplayName("My ASP.NET Portlet")]
[Modes(PortletMode.View, PortletMode.Edit, PortletMode.Help)]
[WindowStates(WindowState.Maximized, WindowState.Minimized, WindowState.Normal, WindowState.Solo)]
[PortletPage(PortletMode.View, "ViewPage.aspx")]
[PortletPage(PortletMode.Edit, "EditPage.aspx")]
[PortletPage(PortletMode.Help, "HelpPage.aspx")]
public class MyPortlet : NetUnity.WSRP.ASP.AspPortlet
{
}
Listing Ten

WSRP Portlet Page is an ASP.NET page that inherits from NetUnity.WSRP.ASP .WsrpPage rather than the standard System.Web.UI.Page class. Other than that, the ASP.NET developer is free to develop as usual, subject to a few restrictions: Ajax currently is not well supported and Session must be managed through the use of the NetUnity.WSRP.StateBag rather than the standard ASP.NET Session. URLs (for redirection and downloading of embedded resources) must be managed using a set of special methods provided by the NetUnity assemblies. Once compiled, the portlet is deployed as a set of ASPX pages and their code behind, and an asmx file that is automatically created by the NetUnity toolkit. This provides the WSDL that is required by a WSRP consumer.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.