Client-Side Developer’s Guide

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

The WebLogic Portal REST API

WebLogic Portal provides a set of web-based, REST-style APIs for retrieving, modifying, and updating portal data dynamically from the client. This chapter discusses the WLP REST API and provides use cases and examples.

Tip: See the WLP REST API Reference online for detailed information on each of the WLP REST commands.

 


What is REST?

REST (REpresentational State Transfer) is an approach for building services that make specific resources available at a URL. A REST service has well defined operations for manipulating the resource. Typically, these operations include reading, writing, editing, and removing. In the case of WLP, a resource might be a portlet, page, or book. For example, the following WLP REST command retrieves a list of portlets in the specified web application:

http://localhost:7001/myWebApp/bea/wlp/api/portlet/list?webapp=myWebApp

Tip: For a good general introduction to REST, see the Wikipedia article “ Representational State Transfer” at http://en.wikipedia.org/wiki/Representational_State_Transfer.

 


What is the WLP REST API?

The WLP REST API focuses on a number of straightforward use cases, such as “retrieving a list of portlets” and “adding a page to a book.” Following the general pattern for REST APIs, the WLP REST API provides commands that read, create, update, and delete portal artifacts. For example, WLP REST commands exist for listing portlets, adding portlets, updating portlets, and deleting portlets. The results of REST commands are persisted through the WLP customization framework. The REST commands discussed in this chapter are not intended for portlet rendering.

Note: Some of the REST API commands only work with streaming portals. Generally, a streaming portal is one that has been configured using the Portal Administration Console. For more information, see File Based and Streaming Portals.

WLP REST API Reference Documentation

The REST API Documentation is available on e-docs.

REST API Use Cases

The WLP REST commands currently provide access to WLP data to support visitor customization features of WLP. The commands allow browser-based tools to interact with and modify a user’s desktop. For example, REST commands are used extensively by the placeable movement feature as well as in the Dynamic Visitor Tool sample application (see The Dynamic Visitor Tools Sample). The commands provide services such as adding, removing, and moving portlets on a page. In general, the WLP REST commands provide a more natural and easy to use alternative to a web services approach.

Note: Some REST commands only return what is not currently visible on the desktop. This supports the use case where users would not want or expect to see a list of, for instance, portlets to add if they were already added to the desktop.

REST Command Format

The format of a WLP REST command is:

<protocol>://<host>:<port>/<webapp>/bea/wlp/api/<type>/<action>/<label>?<params> 

Table 7-1 describes the parts of a WLP REST command:

Table 7-1 REST Command Format  
Command Part
Description
<protocol>
The transport protocol, typically http.
<host>
The IP host name, such as localhost.
<port>
The port number, such as 7001
<webapp>
The name of the web application hosting the services, such as myWebApp. Note that all REST commands also require a webapp parameter. The webapp parameter specifies the specific web application for the command to operate on. The web application specified in the parameter can be different from the web application you post to, as long as it is deployed in the same EAR file.
bea/wlp/api
Standard namespace path used for all REST commands
<type>
The type of portal artifact the command operates on, such as desktop, book, page, portlet, lookandfeel, shell, menu, layout, them.
<action>
The specific action to take, such as list, delete, add, and get.
<label>
The unique label of the object.
command-specific parameters
A list of command-specific URL parameters. See the REST API reference documentation on e-docs for a complete list for each command. Commonly used parameters are described in Commonly Used REST Command Parameters.

Commonly Used REST Command Parameters

Each REST command takes a list of parameters that are described in the REST API reference documentation on e-docs. This section describes three commonly used parameters in greater detail.

The webapp Parameter

The webapp parameter is always required. It specifies the name of the web application on which you are calling the REST command. If you have more than one web application deployed in a given EAR, this parameter lets you easily switch between them. The web application specified with the parameter can be different web application you are posting to (that is, the application specified in the base URL).

For example, in the following command, myWebApp is the application that receives the command, and yourWebApp is the one for which the portlet list is retrieved. Both web applications must be deployed in the same EAR.

http://localhost:7001/myWebApp/bea/wlp/api/portlet/list?webapp=yourWebApp 

The format Parameter

The format parameter can be either xml or json. The default is xml. JSON is an object notation for JavaScript, and is generally easier to work with in a browser environment with JavaScript. See JSON for more information For example:

http://localhost:7001/myWebApp/bea/wlp/api/portlet/list?webapp=yourWebApp&format=json

The scope Parameter

The scope parameter lets you fine tune certain REST commands. This parameter can affect the data retrieved as well as the data updated. The scope parameter can take one of these three values:

Figure 7-2 shows the hierarchy of this scoping in a portal application, the direction of proliferated changes and what tools are typically used to modify at the different levels.

Figure 7-1 Scoping Hierarchy

Scoping Hierarchy

If the value of the scope parameter is set to visitor, then you can optionally specify a user name if you have permissions to do so. WLS administrators, WLP administrators, and community leaders may make changes to other user’s desktops; however, a regular user can only affect his or her own desktop.

Example:

/bea/wlp/api/adminscope/item?webapp=mywebapp&portal=portalpath&desktop=
desktoppath&scope=visitor

This command puts a special token in the HttpSession. This same token is used when an individual user makes a request for a desktop. So if the user “weblogic” logs into a desktop the framework looks at this value to determine what view to bring back. If the value is admin then bring back the default view, otherwise bring back the administrator’s personal view.

Tip: A best practice is to always specify the scope parameter instead of trying to rely on what is in the session because the session can timeout at any point.

REST Command Example

The following REST command retrieves a list of portlets from a portal web application called myWeb that contains just two portlets.

http://localhost:7001/myWeb/bea/wlp/api/portlet/list?webapp=myWeb 

Listing 7-1 shows an example of the type of XML data (the default format) returned by this REST command. This portlet information (such as the portlet label) can then be parsed out and used as input to another REST command, such as a command to add a portlet to a page.

Listing 7-1 Example Response from the List Portlets REST Command
<rsp>
<portlet_summaries>
<portlet_summary>
<label>p1</label>
<title>Portlet One</title>
</portlet_summary>
<portlet_summary>
<label>p2</label>
<title>Portlet Two</title>
   </portlet_summary>
   </portlet_summaries>
</rsp>
Tip: By default, WLP REST commands return data in XML format. You can add the parameter format=json to a command to return a JSON (JavaScript Object Notation) object rather than XML to the client. It is easy to convert the JSON response to a JavaScript object. Once the data is in object form, you can use JavaScript to iterate and access values using familiar dot notation, such as item.title and item.markupName. See also JSON.

 


Disabling REST Commands

You can disable specific REST commands by editing the config file wlp-restapi-config.xml. To disable REST commands, do the following:

  1. Select the Merged Projects view in Workshop for WebLogic.
  2. Open the WEB-INF folder of the web application.
  3. Right-click wlp-restapi-config.xml and select Copy To Project, as shown in Figure 7-2. This copies the file from its library module to your project so that you can edit it.
  4. Figure 7-2 Selecting the REST Config File


    Selecting the REST Config File

  5. Open the file in the editor.
  6. Locate the REST command and set the value of the <enable> element to false, as shown in Listing 7-2.
  7. Listing 7-2 REST Command Definition
    <rest-handler>
        <name>getPortlets</name>
        <path>portlet/list</path>
        <handler-class>com.bea.wlp.rest.portlet.command.GetPortlets
        </handler-class>
        <methods>
            <method>
                <name>get</name>
                <enable>false</enable>
            </method>
        </methods>
    </rest-handler>

 


Basic WLP REST API Examples

This section gives examples of some WLP REST commands and their responses. For a more complete example that includes using Disc to obtain portal information, see Using REST and Disc.

Retrieving Information About a Single Portlet

The following REST command returns details on a single portlet with the label revenue_1 from the web application called “banking.” This result is shown in Listing 7-3.

http://blaster:7041/banking/bea/wlp/api/portlet/details/revenue_1?webapp=dvt
Listing 7-3 Portlet Details
<rsp>
<title>5 Largest Customers</title>
<content_uri>/portlets/revenue/index.jsp</content_uri>
<forkable>false</forkable>
    <fork_render>false</fork_render>
    <is_public>true</is_public>
    <cacheable>false</cacheable>
    <cache_expires>-1</cache_expires>
    <portlet_file>/portlets/revenue/revenue.portlet</portlet_file>
    <deleted>false</deleted>
    <webapp>dvt</webapp>
    <wsrp_user_properties_mode>3</wsrp_user_properties_mode>
    <state_change_flag>0</state_change_flag>
    <requires_url_templates>false</requires_url_templates>
    <templates_stored_in_session>false</templates_stored_in_session>
    <producer_offered_portlet>false</producer_offered_portlet>
    <created_date>2007-10-31 15:54:19.0</created_date>
    <modified_date>2007-10-31 15:54:19.0</modified_date>
</rsp>
Tip: Each of the various portal artifacts (such as pages and books) can be queried to return similar information. Refer to the REST API reference documentation on e-docs for the appropriate command syntax.

Changing the Title of a Portlet

REST commands that update portal data require an HTTP POST method. Listing 7-4 shows a simple script that uses the XMLHttpRequest.open method to post the REST URL.

Listing 7-4 Updating with a POST Method
<script type="text/javascript">
var urlStem =
     'http://localhost:7001/myWeb/bea/wlp/api/portlet/item/restTest_1';
var params = "webapp=myWeb&title=New Title";
var xmlhttp = new bea.wlp.disc.io.XMLHttpRequest();
var url = urlStem + "?" + params;

xmlhttp.open('POST', urlStem, true);
xmlhttp.send(params);

</script>

Moving a Book or Page

The REST commands let you create, delete, and modify objects. Here is an example that illustrates how to move a book from one page to another.

<protocol>://<hostname>:<port>/<webapp>/bea/wlp/api/<type>/<action>/<childtype>/<label>?webapp=<webapp>&format=<format>

Where childtype is a child of the object specified by the type and with the label. For example, moving a page within a book would have a URL such as:

http://mysite.com/flatweb/bea/wlp/api/book/move/bookorpage/mainbook_01

Where mainbook_01 is the label of the book to move the page on. The POST parameters would look like the following:

webapp=flatweb
portal=flatirons
desktop=flatweb
scope=visitor
label=mypage
position=0
alignment=0

The label is the label of the page to move and the position is the position within the book to move to. The scope can be specified as visitor, admin, or library, allowing an admin user to make changes to default instances, library instances, and so on.

Note: The DOM does not automatically reflect changes. Use DHTML on the client to update the page.

 


Using REST and Disc

REST commands by themselves are not sufficient to satisfy all use cases. You need to use the Disc JavaScript API to retrieve portal context objects and the information they contain. This information can then be added to a REST call to update the portal. For example, to move a portlet, you need to use the Disc APIs to get information about the portlet’s current location and add this information to the REST call. The Disc framework is discussed in The WLP Disc Framework.

The following example sections illustrate many of the key concepts around using REST and Disc for client-side portal UI development.

The following sections discuss parts of a sample JSP portlet that is shown in its entirety in Putting It All Together. The portlet lets the user change the page layout by selecting a new layout from a drop down list. The list is populated by querying the portal with the Disc API, and a user’s selection is communicated to the server with a REST command.

Constructing a REST URL Using Disc Context Objects

Using the information obtained from a Disc context object, you can call REST API commands to update the portal. Most REST commands require parameters that can only be obtained from context objects. REST command parameters are listed and described in the WLP REST API Documentation on e-docs.

The function in Listing 7-5 uses Disc context objects to obtain information from the portal that is used to construct REST command parameters. The code is straightforward JavaScript. The REST command requires such parameters as the portlet context, page context, portal path, desktop path, and others. After the parameters are gathered, the REST command URL is constructed.

Listing 7-5 Constructing a REST Command
...
function ${uid}setLayout(layoutName) {
// Get the canvas element to use for output
var canvas = document.getElementById("${uid}canvas");

// Get the portlet context from Disc
var portletContext = bea.wlp.disc.context.Portlet.findByElement(canvas);

// Get the parent page context for the portlet
var pageContext = portletContext.getParentPage();

// Get the application instance from Disc
var appContext = bea.wlp.disc.context.Application.getInstance();

// Create the parameters to pass to the REST command
var params = "";
params += "&portal=" + appContext.getPortalPath();
params += "&desktop=" + appContext.getDesktopPath();
params += "&webapp=" + appContext.getWebAppName();
params += "&layout=" + layoutName;

// Construct the URL for the REST command to change page attributes
var url = "/" + appContext.getWebAppName();
url += "/bea/wlp/api/page/item/" + pageContext.getLabel();
...

Open and Send an XHR Request

After you construct a request to send a REST command, you need to send it to the server. The recommended practice is to use an XHR object to send the command and retrieve the results.

Listing 7-6 shows a code sample that opens an XHR request using a URL and sends a parameter list. The URL and parameter list could be constructed in a similar manner to the techniques discussed in Listing 7-5.

Listing 7-6 Opening and Sending an XHR Request
...
// Get a portal-aware XMLHttpRequest from Disc
var xmlHttpReq = new bea.wlp.disc.io.XMLHttpRequest();
xmlHttpReq.onreadystatechange = function() {
if (xmlHttpReq.readyState == 4) {
if(xmlHttpReq.status == 200) {
var msg = "Layout changed to " + layoutName + ".\n\n";
msg += "Press OK to refresh desktop.";
if (confirm(msg)) {
window.location.reload();
}
} else {
alert("Unable to change layout.");
}
}
};
xmlHttpReq.open('POST', url, true);
xmlHttpReq.send(params);
}
...

Handle the REST Response

Some REST commands return a simple status response. Other commands return additional data, such as detailed information about a portlet. The code sample in Listing 7-7 shows how response data from a REST command might be handled. In this case, the response is a list of available portal layouts that were requested. The response data is passed to a function that parses the list and displays it in a drop down menu. Note that the REST command and its parameters are constructed in a similar manner to that described previously in Listing 7-5.

Listing 7-7 Handling REST Response Data
...
      // Get the application instance from Disc
var appContext = bea.wlp.disc.context.Application.getInstance();

// Construct the parameters for the REST command
var params = "";
params += "?portal=" + appContext.getPortalPath();
params += "&desktop=" + appContext.getDesktopPath();
params += "&webapp=" + appContext.getWebAppName();
params += "&format=json";

// Construct the URL for getting the list of layouts from REST
var url = "/" + appContext.getWebAppName();
url += "/bea/wlp/api/layout/list";
url += params;

// Get a porttal-aware XMLHttpRequest from Disc
var xmlHttpReq = new bea.wlp.disc.io.XMLHttpRequest();
xmlHttpReq.onreadystatechange = function() {
if (xmlHttpReq.readyState == 4) {
if (xmlHttpReq.status == 200) {
// Get the data from the response
var data = eval('(' + xmlHttpReq.responseText + ')');
${uid}displayLayouts(data)
} else {
alert("Unable to retrieve layouts.");
}
}
};
xmlHttpReq.open('GET', url, true);
xmlHttpReq.send(null);
...

Putting It All Together

Listing 7-8 shows a complete JSP file that uses REST and Disc to provide UI for changing the layout of a portal. Note that all of the UI code is on the client-side. Disc is used to obtain information from the portal, REST is used to update the portal, and XHR is used to make asynchronous requests to the server. Figure 7-3 shows the Change Layout portlet in a portal. Note that the portlet requires that the user be logged in.

Figure 7-3 Sample Change Layout Portlet

Sample Change Layout Portlet

Listing 7-8 Sample Portlet JSP
<%--  Copyright (c) 2006-2008 by BEA Systems, Inc. All Rights Reserved. --%>
<jsp:root
version="2.0"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:render="http://www.bea.com/servers/portal/tags/netuix/render"
>
<jsp:directive.page session="false" />
<jsp:directive.page isELIgnored="false" />
<render:encodeName name="" var="uid"/>
<div id="${uid}canvas" style="display: none;">
<div style="text-align: left; margin: 8px; white-space: normal;">
Press the <span style="font-weight: bold">Change Layout</span> button
to display a list of layouts. The current layout for this page will
be selected in the drop-down list, which may be changed by selecting
a different layout. To view the changes click OK in the confirmation
dialog to refresh the desktop.
</div>
<div style="text-align: center; margin: 8px;">
<button name="changeLayout" onclick="${uid}getLayouts();">
Change Layout
</button>
</div>
<div
id="layouts"
style="text-align: center; margin: 8px; visibility: hidden;">
Layouts:&nbsp;
<select
id="${uid}layoutSelect"
onchange="${uid}setLayout(this.options[this.selectedIndex].value)">
</select>
</div>
</div>
<div id="${uid}message" style="text-align: center; padding: 16px;">
<span id="${uid}discMsg" style="display: none">
Please enable Disc to use this portlet.
</span>
<span id="${uid}desktopMsg" style="display: none">
Please use this portlet on a portal desktop.
</span>
<span id="${uid}loginMsg" style="display: none">
Please login to use this portlet.
</span>
<span id="${uid}customizeMsg" style="display: none">
Please enable customization to use this portlet.
</span>
</div>
<script type="text/javascript">
function ${uid}loadInit() {
if (typeof bea == "undefined") {
document.getElementById("${uid}discMsg").style.display = "";
} else {
// Get the application instance from Disc
var appContext = bea.wlp.disc.context.Application.getInstance();

if (appContext.getDotPortal()) {
// Inform the user that the portlet must be on a desktop
document.getElementById("${uid}desktopMsg").style.display = "";
} else if (!appContext.getUserName()) {
// Inform the user that they must login go use the portlet
document.getElementById("${uid}loginMsg").style.display = "";
} else if (!appContext.getCustomizationEnabled()) {
// Inform the user that Disc must be enabled
document.getElementById("${uid}customizeMsg").style.display = "";
} else {
// Display the canvas div and hide the message div
document.getElementById("${uid}canvas").style.display = "";
document.getElementById("${uid}message").style.display = "none";
}
}
}

function ${uid}getLayouts() {
// Get the application instance from Disc
var appContext = bea.wlp.disc.context.Application.getInstance();

// Construct the parameters for the REST command
var params = "";
params += "?portal=" + appContext.getPortalPath();
params += "&desktop=" + appContext.getDesktopPath();
params += "&webapp=" + appContext.getWebAppName();
params += "&format=json";

// Construct the URL for getting the list of layouts from REST
var url = "/" + appContext.getWebAppName();
url += "/bea/wlp/api/layout/list";
url += params;

// Get a porttal-aware XMLHttpRequest from Disc
var xmlHttpReq = new bea.wlp.disc.io.XMLHttpRequest();
xmlHttpReq.onreadystatechange = function() {
if (xmlHttpReq.readyState == 4) {
if (xmlHttpReq.status == 200) {
// Get the data from the response
var data = eval('(' + xmlHttpReq.responseText + ')');
${uid}displayLayouts(data)
} else {
alert("Unable to retrieve layouts.");
}
}
};
xmlHttpReq.open('GET', url, true);
xmlHttpReq.send(null);
}

function ${uid}displayLayouts(data) {
// Get the select element to use for output
var select = document.getElementById("${uid}layoutSelect");

// Get the portlet context from Disc using the select element
var portletContext = bea.wlp.disc.context.Portlet.findByElement(select);

// Get the parent page context for the portlet
var pageContext = portletContext.getParentPage();

// Get the current layout for the page
var layoutContext = pageContext.getLayout();

// Get the markup name for the layout
var layoutName = layoutContext.getMarkupName();

// Set the visibilty of the parent div for the select
var div = select.parentNode;
div.style.visibility = "visible";

// Clear the select box
select.options.length = 0;

// Get the layout details from the response data
var layoutDetails = data.content.layouts;
var layoutDetail = null;

// Iterate over the layoutDetails and create options for each layout
for (var i = 0; i &lt; layoutDetails.length; i++) {
layoutDetail = layoutDetails[i];

// Create a new option element for the layout details
option = document.createElement("option");
option.value = layoutDetail.markup_name;
option.innerHTML = layoutDetail.title;

// Compare the markup name to the current layout and select the match
if (layoutDetail.markup_name == layoutName) {
option.selected = "selected";
}

select.appendChild(option);
}
}

function ${uid}setLayout(layoutName) {
// Get the canvas element to use for output
var canvas = document.getElementById("${uid}canvas");

// Get the portlet context from Disc
var portletContext = bea.wlp.disc.context.Portlet.findByElement(canvas);

// Get the parent page context for the portlet
var pageContext = portletContext.getParentPage();

// Get the application instance from Disc
var appContext = bea.wlp.disc.context.Application.getInstance();

// Create the parameters to pass to the REST command
var params = "";
params += "&portal=" + appContext.getPortalPath();
params += "&desktop=" + appContext.getDesktopPath();
params += "&webapp=" + appContext.getWebAppName();
params += "&layout=" + layoutName;

// Construct the URL for the REST command to change page attributes
var url = "/" + appContext.getWebAppName();
url += "/bea/wlp/api/page/item/" + pageContext.getLabel();

// Get a portal-aware XMLHttpRequest from Disc
var xmlHttpReq = new bea.wlp.disc.io.XMLHttpRequest();
xmlHttpReq.onreadystatechange = function() {
if (xmlHttpReq.readyState == 4) {
if(xmlHttpReq.status == 200) {
var msg = "Layout changed to " + layoutName + ".\n\n";
msg += "Press OK to refresh desktop.";
if (confirm(msg)) {
window.location.reload();
}
} else {
alert("Unable to change layout.");
}
}
};
xmlHttpReq.open('POST', url, true);
xmlHttpReq.send(params);
}

// Add an onload function for this portlet
var ${uid}oldonload = (window.onload) ? window.onload : function () {};
window.onload = function () { ${uid}oldonload(); ${uid}loadInit(); };
</script>
</jsp:root>

  Back to Top       Previous  Next