bea.com | products | dev2dev | support | askBEA |
![]() |
![]() |
|
![]() |
e-docs > WebLogic Platform > WebLogic Portal > Development Guide > Extending Portlets |
Development Guide
|
Extending Portlets
To invoke advanced features in portlets, and make these portlets available to administrators, developers use several tools and many procedures. This section includes information on the following subjects:
Basic Portlet Customization
One of the most basic customizations is moving a portlet from one portal into another. Understanding this procedure will help you understand many of the other tasks in this section, since many procedures and tools are introduced here. This section covers the following basic portlet customizations:
Moving a Portlet Between Portal Web Applications
This section explains the process of moving a portlet from one portal Web application to another, and is based on the assumption that both portals have been deployed correctly. Figure 11-2 shows the two portals with their associated Web applications.
Figure 11-1 Portals and associated Web applications
This example illustrates moving a portlet called flowlet1, shown in Figure 11-2, from one portal Web application (NewPWApp) to another (NextPWApp). Figure 11-2 flowLet1 portlet in the NewWPApp
Take the following steps to add the flowLet1 portlet to NextPWApp portal:
Step 1: Copy J2EE Resources into New Web Application
If you open the flowLet1 portlet inside the E-Business Control Center, you can see it is visible among the available portlets.
Because the original portlet uses a custom Webflow, this file must be moved before the target portal Web application can use this portlet. Figure 11-3 shows the flowLet1 Webflow file in the \webapps directory for NewPWApp being copied into the \webapps directory for NextPWApp.
Figure 11-3 Copying the navigation Webflow
Figure 11-4 shows the portlet folder flowLet1 being copied from the NewPWApp application folder into the NextPWApp Web application folder. The JSPs and images that make up your portlet are stored inside this directory. Figure 11-4 Copying J2EE resources
Now that the J2EE resources have been copied into the new Web application, the metadata can be edited to point to these resources. Step 2: Edit the Target Web Application Metadata Use the E-Business Control Center to add the flowLet1 portlet to the ThatNewPortal portal:
Figure 11-5 Adding flowLet1 to ThatNewPortal
Step 3: Synchronize the Project
Use the E-Business Control Center to sync the project.
Note: For more details on the E-Business Control Center, consult "Setting up the E-Business Control Center" in the Administration Guide at http://download.oracle.com/docs/cd/E13218_01/wlp/docs70/admin/sysadmin.htm
.Figure 11-6 Click Synchronization button
Step 4: Make the New Portlet Visible and Available
The new portlet called flowLet1 is now deployed, but must be made available using the WebLogic Portal Administration Tools.
Figure 11-7 Go to Portal Management
Figure 11-8 Select Default Group Portal
Figure 11-9 Manage Pages and Portlets
Figure 11-10 Click Edit Portlets
Figure 11-11 Select Set Attributes for flowLet1 portlet
Figure 11-12 Set Portlet Attributes
Figure 11-13 Viewing flowLet1 in NextPWApp
Moving a Portlet Between Domains
Assuming both domains are correctly installed and deployed instances of the latest release of WebLogic Portal, the procedure for moving a portlet from one domain to the other is almost identical to that used for Moving a Portlet Between Portal Web Applications.
Figure 11-14 The .portlet file
Finding Missing Resources Through Error Messages
If you are missing necessary portlet resources in a domain, you will receive error messages either at server startup or when you try to access portal pages that use those resources. (Missing portlet resources do not prevent the server from starting.)
For example, you may receive HTTP session errors in your browser such as 404, or render-time errors that say, for example, "Functionality temporarily unavailable." Missing metadata can also cause errors.
Look for error messages in your server's command window to determine which resources are missing. For example, Listing 11-1 shows that a portlet called WebFlowPortlet is missing a file called header.jsp. This message was generated in the command window when the portal page containing this portlet was accessed.
Listing 11-1 Error caused by missing portlet resources
<Jun 12, 2002 10:38:59 AM MDT> <Error> <HTTP> <101214> <Included resource or file "/NewWebApp/portlets/WebflowPortlet/header.jsp" not found from requested resource "/NewWebApp/framework/portal.jsp".>
The E-Business Control Center also catches some errors when you are editing portlets. For example, a warning dialog box alerts you if the portlet you are editing is missing an associated Webflow file.
Creating Categories for Portlets
The E-Business Control Center lets you group portlets into categories for easier management. This section illustrates how to create categories and manage portlets within them.
Preparing to Work With Categories
The steps in this section require that the following preparations be in place:
Warning: Trying to create a new category before a portal has been defined in the E-Business Control Center will generate an error.
Creating Portlets and Categories
Figure 11-15 Creating a new category
The resulting category list should resemble that shown in Figure 11-16.
Figure 11-16 New categories
Note: Selecting one of the portlets makes the three icons to the right available, as shown in Figure 11-17. Figure 11-17 Category icons in toolbar
Moving Portlets and Categories This section explains how to move portlets and categories using the E-Business Control Center.
Figure 11-18 Click Move category
Figure 11-19 Categories and portlets
Figure 11-20 Select a category and click rename
Figure 11-21 Renaming a category
Figure 11-22 Moving portlets into a Category
Figure 11-23 Selecting destination folder
Figure 11-24 Portlets and categories arranged
Adding Portlets to Existing Categories
This section explains how to place new portlets into existing categories. In this example, the following portlets are created:
To add portlets to existing categories, take the following steps:
Note: When naming the portlets, click Select a Category, as shown in Figure 11-25.
Figure 11-25 Select a category for the portlet
Figure 11-26 Placing a new portlet inside an existing category
Figure 11-27 Portlets in their categories
Portlets and the Framework
The BEA WebLogic platform provides extensive support for customizing portlets, including JSP tag libraries designed to expose robust functionality while requiring minimal Java scripting within the actual JSPs that constitute a portlet. Use the information in this section to create the following portlet types:
The remainder of this section explains each portlet type, providing several examples of each and explaining some techniques for creating portlets that best make use of the BEA WebLogic platform.
Simple JSP Portlets
To illustrate some of the power, flexibility, and ease-of-use inherent in the WebLogic Portal platform, this subsection includes the following examples:
The scriptDemo Portlet
The scriptDemo portlet, shown in Figure 11-30, appears to the left on the Home page of an example portal created using the Portal Wizard.
Preparing
Make the following preparations to work through this example:
Before Continuing
Ensure your portal looks similar to that shown in Figure 11-28 before a user is logged in, or that shown in Figure 11-29 with a user logged in.
Figure 11-28 Starting point with anonymous user
Figure 11-29 Starting Point with user logged on
Installing the scriptDemo portlet With the raw materials are in place, you can now transform the portlet by replacing the portlet.jsp to change its behavior. Listing 11-2 shows a very simple scriptlet that illustrates how to use generic Java scriptlets to interact with the Portal framework in a portlet. Listing 11-2 scriptDemo portlet version 1 Steps Take the following steps to place this new code inside the scriptDemo portlet:
<center> Test Portlet </center>
<%
<br><hr>
A Simple Java Scriptlet
<br>
/*
Create a new String variable and set the value to an empty string.
*/
String userName = "";
/*To get the actual user name, first get the java.security.Principal object from the Javax.servlet.http.HttpServletRequest object using the getUserPrincipal() method. The request object is available to the JSP directly. For the Principal object, use the full package name.
*/
java.security.Principal principal = request.getUserPrincipal();
/*If the principal object is null then the user has not logged in. For this example, ignore the not-logged in case by using an if statement to only process the value if it is not null.
*/
if (principal != null)
{
/*
*/
userName = principal.getName();
}
%>
<%-- Display the value of the userName variable using a scriptlet. Note that the scriptlet is embedded in the HTML and is denoted by the <%= %> block.
--%>
The user name is : <%= userName %>
<br>
<BEA_HOME>\portalDomain\beaApps\portalApp\
<PortalWebApp>\portlets\scriptDemo\
Figure 11-30 scriptDemo portlet with anonymous user
Figure 11-31 shows what the code in the scriptDemo portlet displays when a user is logged on. Notice that the user name is filled in.
Figure 11-31 scriptDemo portlet with a user logged on
Note: For more information on using JSP tags in your custom portlets, consult the following resources:
Calling ActiveX Components from a Portlet
To call an ActiveX component from within your portlet, use the HTML <OBJECT> tag, as shown in Listing 11-3 and Listing 11-4.
These examples include a CODEBASE parameter so that if the local machine doesn't have the component installed in their registry, the component can be downloaded from Microsoft.
Note: In these examples, the portal is only communicating with the ActiveX components through HTML, which comes back from the portal to the browser, and tells the browser to load and run the ActiveX component.
Listing 11-3 Calling Outlook Using Active X - Calendar Example
<OBJECT CLASSID="clsid:0006F063-0000-0000-C000-000000000046"
CODEBASE="http://activex.microsoft.com/activex/controls/office/
outlctlx.CAB#ver=9,0,0,3203"
id=OVCtl1 width=100% height=200>
<param name="Folder" value="Calendar">
<param name="Namespace" value="MAPI">
<param name="Restriction" value="">
<param name="DeferUpdate" value="0">
</OBJECT>
Listing 11-4 Calling Outlook Using Active X - Inbox Example
<OBJECT CLASSID="clsid:0006F063-0000-0000-C000-000000000046"
CODEBASE="http://activex.microsoft.com/activex/controls/office/outlctlx.CAB#
ver=9,0,0,3203"
id=OVCtl1 width=100% height=200>
<param name="Folder" value="Inbox">
<param name="Namespace" value="MAPI">
<param name="Restriction" value="">
<param name="DeferUpdate" value="0">
</OBJECT>
Note: ActiveX components only work inside Microsoft Internet Explorer with appropriate security settings which allow them to run.
WebFlow Portlets
This section begins by showing the types of webflow portlets that can be created by the portlet wizard. Next, some fundamental aspects of WebFlow are illustrated using simple scripting examples. The following topics are handled in the section:
Three Webflow Portlets
The Portlet Wizard in the E-Business Control Center can now produce three different types of Webflow portlets:
Preparing
This section illustrates adding new Webflow portlets to the application NewPWApp, as shown throughout this chapter. To work through these examples, make sure the portal server is running, and that portal-project is open in the E-Business Control Center.
Creating a Navigation Bar Webflow Portlet
This procedure shows how to use the portlet wizard to create a Navigation Bar Webflow portlet.
Figure 11-32 Starting the Portlet Wizard
Figure 11-33 Elect to use the Portlet Wizard
Figure 11-34 Naming the Navigation Portlet
Figure 11-35 Associate the portlet with the Home page
Figure 11-36 Select components
Figure 11-37 Select Webflow content type
Figure 11-38 Select Navigation Bar Model
Figure 11-39 Select number of pages
Figure 11-40 Confirm Resource Files Location
Figure 11-41 Confirm Summary
Figure 11-42 Confirm Next Steps
Figure 11-43 Synchronize project
Figure 11-44 Viewing the Navigation Bar Portlet
Creating a Sequential Webflow Portlet
This procedure shows how to use the portlet wizard to create a Sequential Webflow portlet.
Figure 11-45 Starting the Portlet Wizard
Figure 11-46 Elect to use the Portlet Wizard
Figure 11-47 Naming the Sequential Webflow Portlet
Figure 11-48 Associate the portlet with the Home page
Figure 11-49 Select Portlet Components
Figure 11-50 Select Webflow content type
Figure 11-51 Select Sequential model
Figure 11-52 Select number of pages
Figure 11-53 Confirm Resource Files Location
Figure 11-54 Confirm Summary
Figure 11-55 Confirm Next Steps
Figure 11-56 Synchronize project
Figure 11-57 Viewing the Sequential Webflow Portlet
Creating a Hierarchical Webflow Portlet
This procedure shows how to use the portlet wizard to create a Hierarchical Webflow portlet.
Figure 11-58 Starting the Portlet Wizard
Figure 11-59 Elect to use the Portlet Wizard
Figure 11-60 Naming the Hierarchical Portlet
Figure 11-61 Associate the portlet with the Home page
Figure 11-62 Select components
Figure 11-63 Select Webflow content type
Figure 11-64 Select Hierarchical Model
Figure 11-65 Select number of pages
Figure 11-66 Confirm Resource Files Location
Figure 11-67 Confirm Summary
Figure 11-68 Confirm Next Steps
Figure 11-69 Synchronize project
Figure 11-70 Viewing the Hierarchical Portlet
How a Portlet Handles a Refresh Event
To illustrate how portlets can use Webflow, observe how portlets handle the refresh event, as demonstrated in the bold code in Listing 11-5.
Listing 11-5 Adding refresh notification to a portlet
<%@ taglib uri="portlet.tld" prefix="portlet" %>
<%
System.out.println("Calling refresh on flowLet1 portlet.");
%>
<center>
<font size="6" color="green">Portlet 1</font><BR>
<p>
Portlet content with Webflow
<p>
<a href="<portlet:createWebflowURL event="switch1"/>">Next Page</a>
<p>
</center>
Continuing from the previous example, edit the text in the scriptDemo portlet as shown in the following steps:
Figure 11-71 Open console window
<BEA_HOME>\portalDomain\beaApps\portalApp\<PortalWebApp>\
portlets\scriptDemo\
Figure 11-73 Refresh messages in Console
Understanding Webflow Refresh Events in a Portlet
In Webflow, the Refresh event amounts to calling an entity called lastContentUrl, which merely allows you to trigger a portlet to refresh itself without specifying its name. By navigating through the various buttons and controls in the portal in this example while observing the console window for refresh messages, you can see when refresh events are caused by certain actions. To look more closely at the Webflow associated with flowLet1, take the following steps:
Figure 11-74 Opening Webflows within Portal Web Application
Figure 11-75 Nodes linked to portal_lastContentUrl
By default, refresh is always invoked on an entire portal, and can be called on every portlet. Any portlet with its own Webflow can be made to respond to all refresh events. To make this default behavior for a portlet, use the Webflow editor to open the portlet's Webflow and set *.refresh proxynode to lastContentUrl.
For an in-depth look at using Webflow, consult Setting Up Portal Navigation.
Making a Portlet Respond to a Custom Event
To explain custom events, consider the navigation mapping in the Webflow for flowLet1 portlet, shown in Figure 11-76.
Figure 11-76 Navigation nodes in flowLet1 Webflow
The navigation between content1.jsp and content2.jsp is accomplished using pre-defined events called switch1 and switch2. By selecting one of the content nodes, you can examine the properties of the Webflow that links content1.jsp with content2.jsp in the flowLet1 portlet. The properties of the content2 presentation node are shown in detail in Figure 11-77. Figure 11-77 Mappings for content2
Defining a Custom Event Figure 11-78 shows how a custom event is assigned to a new presentation node. This event is named myCustomEvent, and the Event connector tool is used to link presentation node content2 with presentation node content3. Figure 11-78 Defining myCustomEvent
Invoking the Custom Event To call the custom event in the portlet, include the following code in your JSP: Figure 11-79 shows the third screen of flowLet1 after a new presentation node, called content3.jsp, has been added. Figure 11-79 The third page of flowLet1 portlet
<a href="<portlet:createWebflowURL event="myCustomEvent"/>">Next Page</a>
Sharing State from One Portlet to Another Share state from one portlet to another by placing the arguments into the HttpSession object using an Input Processor. For instance, if portletA uses a form named "foo", use the IP to extract the "foo" form data, and portletB can get the form data from the Pipeline Session. Note: For more information on Input Processors, consult Setting Up Portal Navigation. Web Service Portlets Web Services are reusable software components that enable applications to interact efficiently and in a loosely-coupled manner; they are used internally for fast and low-cost application integration, or made available to customers, suppliers or partners over the Internet. Enabling portlets to consume Web Services, either internally or over the Internet, introduces a range of new benefits - and introduces some new developer issues as well. Note: For the sake of simplicity, the examples shown in this section show portlets connecting to Web Services that are locally hosted. This section contains information on the following topics:
Using the Portlet Wizard to Create Web Services Portlets
The Portlet Wizard can create portlets that consume Web Services in three different ways:
This option can be used to create a portlet that calls a Web Service asynchronously through client polling. The section "Calling Web Services Asynchronously" includes instructions on creating this type of portlet.
This section shows how to use the Portlet Wizard to create a portlet of each type.
Preparation
Start the WebLogic Workshop Examples Server by navigating to Programs
Note: This example shows the scriptDemo, flowLet1 and flowLet2 portlets removed, but you complete these Web Service portlet examples without removing the old portlets from the portal.
Avoiding Namespace Collisions
Both the previous Call Generation and the Interface examples create instances of identical classes which run within the same portal namespace. To prevent namespace collision, the local instances of each class must be given unique names. In the second and third portlets, the implementation classes are re-named, as shown before the code samples.
Creating a Simple Form-Driven Web Service Portlet
The first portlet sends simple form input to the AccountEJBClient Web Service, creating a simple bank account object hosted at the WebLogic Workshop examples server.
Create the Portlet Called formLet Using the Portlet Wizard
Figure 11-80 Select Web Services content type
Figure 11-81 Select Server Location
Figure 11-82 Select Generated Code Types
Figure 11-83 Click Add Web Services
Figure 11-84 Enter the URL of the WSDL
Figure 11-85 Retrieving Operations
Figure 11-86 Select the createNewAccount operation
Figure 11-87 Code Preview
Figure 11-88 Select/Confirm Resource Files location
Figure 11-89 Confirm Summary of Files
Figure 11-90 Choose Next Steps
Note: For this example, we'll create all three portlets first, then deploy them at once at the end.
Creating a Call-Generation Web Service Portlet
The Call Generation portlet enables the user to make a deposit to a bank account by remotely invoking classes hosted within the Web Service hosted on the WebLogic Workshop examples server.
Create the Portlet Called callgenLet Using the Portlet Wizard
Figure 11-91 Select Web Services content type
Figure 11-92 Web Service(s) screen
http://localhost:7001/samples/ejbControl/
AccountEJBClient.jws?WSDL
Figure 11-93 Adding another Web Service WSDL
Note: Notice the parameter list below the operation.
Figure 11-94 Selecting the listBigAccounts operation
Figure 11-95 Code Preview
Note: Within Listing 11-6, the following entries, in boldface within the code, have been shortened:
callImpl was originally p_sdl_AccountEJBClient_AccountEJBClient_Impl
callSoap was originally p_sdl_AccountEJBClient_AccountEJBClientSoap
Listing 11-6 Call Generation Portlet code
<%@ include file="callgenlet1_include.inc" %>
<%@ taglib uri="portlet.tld" prefix="portlet" %>
<%@ taglib uri="i18n.tld" prefix="i18n" %>
<%@ page import="com.bea.portal.appflow.PortalAppflowConstants"%>
<%@ include file="/framework/resourceURL.inc"%>
<%
sdl_AccountEJBClient.AccountEJBClient_Impl callImpl = new sdl_AccountEJBClient.AccountEJBClient_Impl();
sdl_AccountEJBClient.AccountEJBClientSoap callSoap = callImpl.getAccountEJBClientSoap();
%>
<%
double threshold = 1000;
%>
<%=cnvrtSC(String.valueOf(callSoap.listBigAccounts(threshold)))%>
Figure 11-96 Select/Confirm Resource Files location
Figure 11-97 Confirm Summary of Files
Figure 11-98 Choose Next Steps
Creating a Web Services Interface Portlet
This portlet searches for accounts with a balance over a threshold set within the portlet, and lists them in the portlet. What is significant is the way in which this portlet communicates with the Web Service: the portlet uses classes implemented according to the self-describing WSDL called listBigAccounts.
Create the Portlet Called interFaceLet Using the Portlet Wizard
Figure 11-99 Select Generated Code Type
Note: In the Web Service(s) screen for Interface Generation portlets, notice that no operations are available. This is because you are being provided the interface description and must implement the required methods yourself.
Figure 11-100 Code Preview screen for interFaceLet
Listing 11-7 Code for interFaceLet
<%@ include file="interFaceLet_include.inc" %>
<%@ taglib uri="portlet.tld" prefix="portlet" %>
<%@ taglib uri="i18n.tld" prefix="i18n" %>
<%@ page import="com.bea.portal.appflow.PortalAppflowConstants"%>
<%@ include file="/framework/resourceURL.inc"%>
<%
sdl_AccountEJBClient.AccountEJBClient_Impl intImpl = new
sdl_AccountEJBClient.AccountEJBClient_Impl();
sdl_AccountEJBClient.AccountEJBClientSoap intSoap =
intImpl.getAccountEJBClientSoap();
...
*/%>
Figure 11-101 Select/Confirm Resource Files location
Figure 11-102 Confirm Summary of Files
Figure 11-103 Choose Next Steps
Figure 11-104 Synchronization Complete
Deploying the Web Services Portlets
Now that they are all created and installed, what remains is to make them available to the WebLogic Server instance. This is done by simply re-deploying the Portal Web Application in which these portlets are to run, according to the following procedures:
http://<host>:<port>/console
Figure 11-105 Left tab of console: Deployments
Figure 11-106 Go to Portal Management
Figure 11-107 Select Default Group Portal
Figure 11-108 Manage Pages and Portlets
Figure 11-109 Click Edit Portlets
Viewing the Web Services Portlets
Now that they are all deployed and placed within the same portal page, observe the functionality they provide by taking the following steps:
http://<host>:<port>/NewPWApp/
The result should resemble that shown in Figure 11-110.
Figure 11-110 Web Services portlets before accounts have been entered
Figure 11-111 Web services portlets with some account activity
Note: For more information on Web Services, consult "Building Web Services on WebLogic Platform" at http://download.oracle.com/docs/cd/E13196_01/platform/docs70/interm/webserv.html and "Introduction to WebLogic Workshop" at http://download.oracle.com/docs/cd/E13226_01/workshop/docs70/index.html.
Calling Web Services Asynchronously
BEA WebLogic Portal 7.0 enables portlets to participate in asynchronous communication with Web Services such as conversations. This example shows how to create a simple conversation portlet that interacts with a Web Service hosted on the local server.
Figure 11-112 Conversation Web Services Portlet
About the Conversation Portlet The portlet created in this example contains three button-activated actions:
Preparation
Creating the Conversation Portlet
To create and deploy a sample Conversation portlet, follow these steps.
Figure 11-113 Creating the conversation portlet
Listing 11-8 content.jsp for Conversation Web Services Portlet
<%@ include file="Conversation_include.inc" %>
<%@ taglib uri="portlet.tld" prefix="portlet" %>
<%@ taglib uri="i18n.tld" prefix="i18n" %>
<%@ page import="org.openuri.www.StartRequest"%>
<%@ page import="org.openuri.www.GetRequestStatusResponse"%>
<%@ page import="org.openuri.www.x2002.x04.soap.conversation.StartHeader"%>
<%@ page import="org.openuri.www.x2002.x04.soap.conversation.ContinueHeader"%>
<%@ page import="weblogic.xml.schema.binding.internal.builtin.VoidType"%>
<%@ page import="com.bea.portal.appflow.PortalAppflowConstants"%>
<%@ page import="com.bea.portal.appflow.PortalAppflowConstants"%>
<%@ include file="/framework/resourceURL.inc"%>
<%
DL_wsdl_Conversation.Conversation_Impl conversationImpl = new
DL_wsdl_Conversation.Conversation_Impl();
DL_wsdl_Conversation.ConversationSoap soap =
conversationImpl.getConversationSoap();
%>
<%
String target = request.getParameter("target");
String conversationID = session.getId();
if ( conversationID == null )
conversationID = "";
%>
<portlet:form event="<%= PortalAppflowConstants.PORTLET_REFRESH %>">
<table border="0" align="center">
<tr>
<td width="100%" align="center">
<table border="0" align="left">
<tr>
<%
if ( target != null
&& target.equals("start")
&& true )
{
try
{
StartHeader startHeader = new StartHeader(conversationID,
"http://localhost:7001/samples/async/Conversation.jws");
VoidType startResponse = new VoidType();
StartRequest begin = new StartRequest(false);
startResponse = soap.startRequest(begin, startHeader);
%>
<td><%=cnvrtSC("Conversation started with ID: " +
String.valueOf(conversationID))%></td>
<%
}
catch (java.rmi.RemoteException e)
{
%>
<td><%=cnvrtSC("Duplicate conversation id for start: " +
String.valueOf(conversationID))%></td>
<%
e.printStackTrace();
}
}
%>
</tr>
</table>
</td>
</tr>
<tr>
<td width="100%" align="center"><input type="submit" name="start"
value="Start"></td>
</tr>
</table>
<br><br>
<input type="hidden" name="target" value="start">
</portlet:form>
<portlet:form event="<%= PortalAppflowConstants.PORTLET_REFRESH %>">
<table border="0" align="center">
<tr>
<td width="100%" align="center">
<table border="0" align="left">
<tr>
<%
if ( target != null
&& target.equals("continue")
&& true )
{
try
{
ContinueHeader continueHeader = new
ContinueHeader(conversationID);
GetRequestStatusResponse status = soap.getRequestStatus(null,
continueHeader);
String result = status.getGetRequestStatusResult();
%>
<td><%=cnvrtSC("Response: " + String.valueOf(result))%></td>
<%
}
catch ( Exception e )
{
e.printStackTrace();
}
Deploy the conversation portlet according to the instructions in the section Deploying the Web Services Portlets.
Figure 11-114 Starting the conversation
Error Handling within Web Services Portlets In a production scenario, the Web Services to which your portlets connect are typically hosted elsewhere, and are out of your control. The portal framework enables portlets to generate two errors specifically designed to handle Web Services problems: JAXRPCException: If a Web service is unavailable at run-time, the portlet will cause the throw a javax.xml.rpc.JAXRPCException. Add error handling to your .JSP by catching the exception in a generated portlet. Note: The JAXRPCException applies to cases where the connection is refused, not when there is a delay in service. SOAPFaultException: When a Web service cannot handle the SOAP request generated from the Web Service Portlet Wizard, a javax.xml.rpc.soap.SOAPFaultException is thrown. You should catch this exception within your .JSP to protect from compile failures.
Performance Tuning
This section covers performance issues related specifically to WebLogic Portal, including JDBC and Thread settings and several cache settings. Many factors effecting the performance of your portal application are specific to WebLogic Server. For information on making those adjustments, consult the WebLogic Server Performance and Tuning guide at http://download.oracle.com/docs/cd/E13222_01/wls/docs70/perform/index.htmll.
Using Caches to Tune Performance
To adjust caching for production Web site, examine the following factors:
Adjust Caching for Content Management
To optimize content-management performance for your production Web site, the Content Manager uses the caching framework to configure and manage the following caches:
documentContentCache
documentMetadataCache
documentIdCache
The content management JSP tags provide an additional set of caches, which you can access by doing the following:
For the cm:select, cm:selectById, pz:contentQuery, and pz:contentSelector JSP tags, use the useCache attribute whenever possible. Doing so avoids a call to DocumentManager and, in the case of pz:ContentSelector, to the Rules Manager.
To clear cached content when user and/or document attributes change, use the remove method of com.bea.p13n.content.ContentCache. For more information, see the WebLogic Portal Javadoc. for com.bea.p13n.content.ContentCache.
For the cm:select, cm:selectById, pz:contentQuery, and pz:contentSelector JSP tags, set the cacheScope attribute to application whenever possible. This application scope applies to the Web application, not to the enterprise application, as shown in Listing 11-9.
Listing 11-9 Setting cacheScope to application
<cm:select id="myDocs" query="riskFactor = 'Low'"
useCache="true" cacheId="myDocs"
cacheScope="application"
max="10" cacheTimeout="300000" />
The application cache type is global instead of per-user and should speed up queries by avoiding a call to the DocumentManager EJB.
For pz:contentSelector, set the cacheScope attribute to application only when you want to select shared content. For example, you create an application that uses an application-scoped cache to select content for non-authenticated users. Because it uses the application scope, all non-authenticated users see the same content. For authenticated users, your application provides personalized content by switching to a session scoped cache.
Whenever you can predict the next document that users will view based on the document that they are currently viewing, load the next document into the cache before users request it. This "forward caching" will greatly improve the speed at which WebLogic Portal responds to user requests (assuming that your prediction is correct; forward caching a document that no one requests will only degrade performance and scalability).
Listing 11-10 contains a snippet of a JSP with an example of forward caching a document:
Listing 11-10 Forward caching a document
<%-- Get the first set of content --%>
<cm:select id="myDocs" query="riskFactor = 'Low'"
useCache="true" cacheId="myDocs"
cacheScope="application"
max="10" cacheTimeout="300000" />
<%-- Generate a query from each content's relatedDocId --%>
<% String query = null; %>
<es:forEachInArray array="<%=myDocs%>" id="myDoc" type="com.bea.p13n.content.Content">
<% String relId = (String)myDoc.getProperty("relatedDocId", null); %>
<es:notNull item="<%=relId%>">
<%
if (query != null)
query += " || ";
else
query = "";
query += "identifier = '" +
ExpressionHelper.toStringLiteral(relId) + "'";
%>
</es:notNull>
</es:forEachInArray>
<%-- Load the related content into the cache via cm:select --%>
<es:notNull item="<%=query%>">
<cm:select query="<%=query%>" id="foo" useCache="true" cacheId="relatedDocs"
cacheScope="session" max="10" cacheTimeout="300000" />
</es:notNull>
For more information on content management JSP tags, see "Personalization JSP Tags" in the JavaServer Page Guide at http://download.oracle.com/docs/cd/E13218_01/wlp/docs70/jsp/p13njsp.htm
.Property Caching in a Clustered Environment
To decrease the amount of time needed to access user, group, and other properties data, the WebLogic Server Configurable Entity and Entity Property Manager use the cache framework to configure and manage the following caches:
ldapGroupCache
ldapUserCache
entityPropertyCache
entityIdCache
unifiedProfiletypeCache
propertyKeyIdCache
Note: By default, these property caches are enabled.
With property caching enabled in a clustered environment, each server in a cluster maintains its own cache; the cache is not replicated on other servers. In this environment, when properties that are stored in the caches change on one server, they may not change on another server in a timely fashion. In most cases, immediate or quick access to properties on another server is not necessary: user sessions are pinned to a single server, and even with caching enabled, users immediately see changes they make to their own settings on the server.
If a user and an administrator are pinned to different servers in the cluster and the administrator changes a user's properties, the user may not see the changes during the current session. You can mitigate this situation by specifying a small Time-To-Live (TTL) setting.
If you require multiple servers in a cluster to have immediate access to modified properties, disable property caching.
Adjust Caching for the Discount Service
To reduce the amount of time the Order and Shopping Cart services need to calculate order and price information that include discounts, the Discount Service uses the caching framework to create and manage the following caches:
When a customer adds an item to the shopping cart, removes an item from the shopping cart, checks out, or confirms an order, the Pricing Service is responsible for determining the price of the items in the cart. To calculate the effect of discounts on the shopping cart, the Pricing Service requests the Discount Service to retrieve information about all global discounts and about any campaign discounts that apply to the current customer.
The first request for information about discounts requires a separate call to the database for each discount that applies. For example, if you have defined one global discount and if a customer is eligible for two campaign-related discounts, the Discount Service makes three calls to the database. To decrease the response time for any subsequent requests, the Discount Service uses the caches.
Adjusting the discountCache
The discountCache contains data for campaign discounts. For maximum performance, set the capacity to the number of campaign discounts that are currently deployed. A larger capacity will potentially use more memory than a smaller capacity.
The Time-To-Live (TTL) property determines the number of milliseconds that the Discount Service keeps the information in the cache. After the cache value times out, the next request for the value requires the Discount Service to call the database to retrieve the information and then cache the value. A longer TTL decreases the number of database calls made over time when requesting cached objects. In a clustered environment, the TTL is the maximum time required to guarantee that any changes to global discounts are available on all servers.
Adjusting the globalDiscountCache
The Maximum Number of Entries property for global caches does not need to be modified.
The time-to-live property determines the number of milliseconds that the Discount Service keeps information in the global-discount cache. After the Time-To-Live (TTL) expires, the next request for global discount information requires the Discount Service to call the database to retrieve the information and then cache the value. A longer TTL decreases the number of database calls made over time when requesting cached objects. In a clustered environment, the TTL is the maximum time required to guarantee that any changes to campaign discounts are available on all servers.
Discount-Service Caches in Clustered and Non-Clustered Environments
In either environment (clustered or non-clustered), when you change a discount priority, end date, or its active/inactive state, WebLogic Portal flushes the discount from the appropriate cache. Changes to a campaign discount flush only the specific discount from the campaign-discount cache. Changes to a global discount flush all discounts from the global-discount cache.
For example, you log in to a WebLogic Portal host named bread and deactivate a campaign discount named CampaignDiscount1. WebLogic Portal flushes the CampaignDiscount1 from the campaign-discount cache on bread.
In a clustered environment, other machines in the cluster continue to use their cached copy of the discount until the TTL for that discount expires.
Adjust Group Membership TTL in the Caching Realm
The WebLogic Server Caching realm stores the results of both successful and unsuccessful realm lookups. It does not use the WebLogic Portal caching framework.
The Caching realm manages separate caches for Users, Groups, permissions, ACLs, and authentication requests. It improves the performance of WebLogic Server by caching lookups, thereby reducing the number of calls into other security realms.
WebLogic Portal enables the Caching realm by default. While all of the caches in the Caching realm can improve performance, the Time-To-Live (TTL) value for the Group Membership Cache in particular can affect the performance of WebLogic Portal.
In addition, note that if you delete a user from the system without first removing the user from a group, then the system continues to recognize the user until the TTL for the Group Membership Cache expires.
For information on adjusting the Group Membership TTL, refer to the WebLogic Server Administration Guide at http://download.oracle.com/docs/cd/E13222_01/wls/docs70/adminguide/index.html.
Tuning Thread / Connection Parameters in JDBC
Certain performance problems encountered in the portal may be corrected by changing config.xml entries to reduce to thread count for the default execute queue in WLS lower than the connection pool maximum capacity specified for the commercePool. The basic formula should make the number of connections in the connection pool equal to the number of threads + 1.
For information on adjusting threads and connection pools, consult "Tuning JDBC Connection Pool Maximum Capacity" at
http://download.oracle.com/docs/cd/E13222_01/wls/docs70/perform/WLSTuning.html#1117878.
![]() |
![]() |
![]() |
![]() |
||
![]() |
![]() |
![]() |
![]() |
![]() |
|
![]() |