![]() |
![]() |
|
|
Building a Custom Portal Step-by-Step
This document is a tutorial for building your own custom e-commerce portal. It assumes minimal knowledge of BEA products, and some knowledge of HTML and JSP. If you are new to WebLogic Server 5.1 (WLS) and WebLogic Commerce Server 3.1 (WLCS), and want to get up to speed quickly, this document is for you.
It is recommended, but not required, that you review the Personalization Tour before proceeding with this document.
This topic has the following sections:
Note: Throughout this chapter, the environment variable WL_COMMERCE_HOME is used to indicate the directory in which you installed the WebLogic Commerce Server 3.1 and WebLogic Personalization Server 3.1 software.
Introduction
Internet portals are a key part of many eCommerce applications. Portals provide an entry point to the Internet as well as value-added services such as searching and application integration. The WebLogic Personalization Server allows you to quickly assemble both Business-to-Consumer and Business-to-Business portals that require personalized application content on the Internet.
The WebLogic Personalization Server enables web developers to create portal web pages and personalized application content for each portal user. The WebLogic Personalization Server uses JSPs, a part of the J2EE specification, in conjunction with a special library of JSP tags, standard HTML, Enterprise Java Beans (EJB), portal end user and the portal administration tools, and a pre-configured database to store portal component entities.
Terminology
Before you can begin building your portal, familiarize yourself with the following terminology.
Note: You are not required to use the Portal Framework. You may build your site from scratch, although, it is not recommended for new users of the system.
How to Use This Chapter
The WebLogic Personalization Server includes a Portal administration tool that allows you to quickly build a basic portal using the Portal Framework. Techniques for using the Portal administration tool are documented in the chapter Creating and Managing Portals in the WebLogic Personalization Server User's Guide. That chapter also includes step-by-step instructions for building the Acme Demo Portal. This tutorial will not repeat the information presented in the User's Guide.
The goal of this chapter is to get you started building your own custom portal. It will cover many techniques for customizing the Portal Framework. This chapter also provides many small projects which will demonstrate how to use these techniques. The code fragments used to build these projects are included.
However, this chapter does not explain what every line of code does in these samples. It provides general guidance in understanding how an example works, but the details are left as an exercise to the user. The reason for this is that the best way to learn how to develop with WebLogic Personalization Server is to reverse engineer code written by others. Once you get each example working, spend some time experimenting with the code. A good rule of thumb is to not proceed to the next example until you know what each line of code does in the previous example.
Creating the Framework for Your Custom Portal
This section describes how to build a custom portal. At the end of this section, you will have created a copy of the example portal (which uses the Portal Framework) which you will alter as you build your custom site. It is important that you use the example portal as a base since it does provide extensive functionality. Later, when you gain familiarity with the product, you can re-engineer your custom site one piece at a time.
Note: It is not recommended for new WebLogic Personalization Server developers to attempt to build a portal from scratch.
This section will walk you through the process one step at a time. It is primarily intended to help you get the framework of your custom portal up and running and does not attempt to explain the details of this process. In later sections, you will be introduced to the details in a more rigorous way.
Installing WebLogic Personalization Server
If you have already installed WebLogic Personalization Server 3.1, begin this procedure at step 14.
To install WebLogic Personalization Server, follow these steps:
Note: There are two errors in the Service Pack 6 install instructions. 1) Be sure to copy weblogic510sp6.jar and weblogic510sp6boot.jar to the lib subfolder and not the root folder. 2) Copy weblogic-tags-510.jar to the lib folder. For more information, consult the WebLogic Commerce Server with WebLogic Personalization Server Installation Guide.
Note: It is very important to look at the console window and inspect the output for exceptions. If any exceptions occurred during startup, you will need to resolve the problem before WebLogic Server will work properly.
Note: Windows users should modify the properties of their console window to extend the screen buffer to at least 500 lines. Accomplish this by right-clicking on your console window's title bar and choosing "Edit..." from the pop-up menu. Go to the Layout tab and change the Screen Buffer height to be at least 500. When you click OK, it will ask if you want to apply these changes for future windows of the same title. Check this option.
Note: You may also shut down the server by pressing CTRL-C in the console window in which the server is running. This method is not recommended in production environments since it may cause database connections to be consumed until a database server reboot.
Note: It is very important to look at the console window and inspect the output for Java exceptions. If any exceptions occurred during startup, you will need to resolve the problem before WebLogic Personalization Server will work properly.
Note: If you have errors related to foundation.jar not loading properly, your WebLogic Server Service Pack update did not succeed. Go back and reinstall the Service Pack.
You have completed the installation of WebLogic Personalization Server 3.1. Now you will proceed with setting up the framework for your custom portal.
Setting up the Portal Framework
To set up the framework for your custom portal, follow these steps:
Note: Do not use spaces in this folder name or you will have complications in step 20.
Note: Make sure you type this exactly as you see it. It is case sensitive and spaces should not be used.
Note: Clicking Back will fail with an "Authorization Failed" message if your browser does not allow cookies. In this case, you must change your browser settings to allow cookies for the administration tool to function properly.
Note: Do not change the repositorydir property.
Note: Not all of the displayed portlets may be valid for your new portal. If any portlets were added for another portal on the server, these portlets may have a different relative path from %WL_COMMERCE_HOME%/server/public_html/portals. Adding a portlet located in another portal will give your users a run-time error. To avoid this problem, use only the portlets located in the %WL_COMMERCE_HOME%/server/public_html/portals/repository/portlets subfolder (consult the list below).
The following list describes the available portlets.
Defined Portals-Displays the portals defined in the system. Uses the <es:forEachInArray> and <es:simpleReport> tags.
Defined Portlets-Displays the portlets defined in the system. Uses the <es:forEachInArray> and <es:simpleReport> tags.
News Index-Demonstrates the use of Content Management tags.
News Viewer-Displays content driven from content_index.jsp. Use in conjunction with News Index.
Quote-Displays stock quotes. Demonstrates how to redirect a portlet to an external site.
Dictionary-Demonstrates how to redirect a portal to an external site.
Search-Demonstrates how to redirect a portal to an extend site.
Group To Do List*-Displays a Group To Do list. Requires user to be logged in.
My To Do List*-Displays a My To Do list. Requires user to be logged in.
Bookmarks*-Displays the bookmarks associated with the current user. Requires user to be logged in.
Open a browser window and type in http://localhost:7501/application/eTestPortal.
In your browser, you should see a Web page with an Acme logo. You should see all the portlets which you defined as being visible in the Portlet Administration page. Portlets that require a user login (marked with an * above) will not display until you are logged in.
Note: It is important to look at the console window to make sure exceptions are not being thrown.
Troubleshooting
If you do not see the portal page or have exceptions, make sure you have not made the following common mistakes:
Problem: Server not responding
Problem: Server returns error
You have completed the first step in building your own custom portal.
Repository Directory
An important concept to understand is the repository directory. The repository directory (specified by your repositorydir property in your property set) is the location where the server looks to find a resource if it cannot find it in your working directory (specified by your workingdir property in your property set). If you followed the previous instructions, you did not populate your working directory with any files. Therefore, when you navigated to your site in "Setting up the Portal Framework," step 17, the server failed to find the files (specifically, your Home page portal.jsp) in your working directory and so it found them in your repository directory instead. It is important that you understand how this works.
Before you proceed, take a few moments now to read back through this section and review the steps you followed. Although you may not understand why each step was necessary, it is helpful to have a clear understanding of what the steps were. Also, spend some time looking in the repository directory to see what resources are provided by default. The repository directory contains the Portal Framework and resources specific to the Acme portal and its portlets.
The rest of this chapter is devoted to making incremental changes to your copy of the example portal so that it is transformed into your own custom portal. In the process, you will replace many pieces of the example portal, though your site will still be based on the Portal Framework.
Simple Customizations
The previous section described how to establish a platform for your custom portal. This section assumes that you successfully completed this process. Whereas the last section had a strictly-defined process, the following sections are project based. It is recommended that you do these projects in order, although it is not required. Each project will list any prerequisite projects.
Note: Remember that your browser may cache pages. If you make modifications to your site and they do not appear in your browser, then click Refresh. This will circumvent the cache and get an updated page from the WebLogic Personalization Server server. If this fails to work, you should flush your browser's disk cache, as follows:
If problems continue, try switching to a different browser (IE/Netscape) to view the page.
Project 1: Customizing the Acme Logos
Start by removing the Acme logo and replacing it with your own brand image, as follows:
Note: WebLogic Personalization Server will automatically detect the new images and load them in, so you do not need to restart the server. Remember to click Refresh in your browser. If after clicking Refresh, you do still do not see your new image, you may have to flush your browser's disk cache.
Project 2: Customizing the Choice of Portlets
In the previous section, you were asked to randomly choose a set of portlets to assign to your portal. Now that you are up and running, it is time to revisit the choice of portlets you made. Log on to the administration tool. Go to the Portal Manager and double click the name of your portal under the Portals title bar. You will see the portal edit page. Click the +/- icon on the portlets title bar. The portlet selection editor will appear.
Experiment with the controls and choose the portlets that you want to include. At this time, you can choose from only the prebuilt portlets. In later sections you will be building your own portlets. When choosing a portlet for your site, you may also specify whether it is visible by default, not visible but available, or not available at all.
For more information, see Creating and Managing Portals in the WebLogic Personalization Server User's Guide.
Project 3: Customizing the Layout of Portlets
If you look carefully at your portal, you will notice that your portal has three main sections: a title bar, a container in the middle for a number of smaller components, and a footer. The smaller components in the middle space are called "portlets." Each portlet is written as an independent JSP or HTML file. Each portlet is responsible for its own contents, while the portal page is responsible for laying the portlets out in columns.
You can customize this layout in two ways:
Note: As an administrator you may define how the layout appears by default, but the user may override your choices.
Log on to the administration tool. Go to the Portal Manager and then click the name of your portal under the Portals title bar. You will see the portal edit page. By editing the portal definition, you may change the number of columns used to display your portal. To change which portlets are in which column, you need to use the layout editor.
For more information, see Creating and Managing Portals in the WebLogic Personalization Server User's Guide.
Project 4: Describing Your Users
Your portal site will most likely have a number of categories of users. WebLogic Personalization Server recognizes this by supporting a feature called User Groups. With this feature, you can define a hierarchical set of groups to which you can assign users. Additionally, you will may have a number of predefined users that you would like to initially set up. As part of this process, you will want to assign these people to one or more of the groups you have set up. This project details how to build this into your portal.
For more information, see Creating and Managing Portals in the WebLogic Personalization Server User's Guide
.
Writing Your Own Portlets
Creating the Framework for Your Custom Portal instructed you how to get up and run with your custom portal by copying the example portal. Simple Customizations showed you how to alter the logo images and use the administration tool to customize your portal. Now, this section will show you how to build your own functionality into your custom portal.
In this section, you will see how to build static portlets and portlets that change based on state information retrieved from WebLogic Personalization Server. Once you have mastered the essence of portlet writing, you will learn about advanced functionality such as maximized porlets and inter-portlet communication in the next section, Advanced Portlet Functionality.
Note: In the following projects, you will be registering your portlets and adding them to your portal using the administration tool. When doing these activities or when editing the portlet definition after creation, you may not see the changes to your portal in your browser even after flushing the browser cache. This is due to server-side caching. In order to force a rebuild of your portal page, you must log in if you are logged out, or log out if already logged in to see your changes take effect.
Project 5: Building a Static Portlet
The fundamentals of portlet writing are not difficult. As you will see, the construction of a static portlet is quite easy. The complexity of portlets come when they become dynamic. The first portlet project is a static portlet.
When you view your portal, your browser is displaying an HTML page to you. If you "View Source" on your portal, you will not see any JavaServer Page tags, although JSP was used to author the document. This is because the server processed the JSP input and output the HTML to your browser. In exactly the same way, before your portlet is placed on the portal page, it is processed and converted into HTML if it was not already. With this in mind, think of a portlet as just a small Web page.
For this static portlet project, you are not going to use a JSP. You will build just an HTML fragment that will get included into the portal page. What follows is your first portlet.
welcome.html
<p align=center>
<h1>Welcome!</h1><br>
This portal contains the projects built by following the WLCS tutorial.
</p>
Students of HTML will recognize this as just a simple static HTML fragment. There really is nothing special about this HTML.
To make the HTML fragment above into a portlet, follow these steps:
Note: Windows users using WordPad or MS-Word should Save As a text document; otherwise, extra unwanted characters will be dumped into the text stream.
Note: Be sure to click the Create button on the Portlet title bar and not the one on the Portal title bar.
You have now added new functionality to WebLogic Personalization Server.
Project 6: Building a Simple Dynamic Portlet
Now that you see how easy it is to build portlets, your next step is to add some dynamic behavior to your portlet. For this, you will need to create a JavaServer Page file, not HTML. With the power of JSP, you can query the WebLogic Personalization Server for information, and vary the output depending on the results of your queries.
In this project, you will build a portlet that will detect if the user of the browser is logged on to the portal. If not, this portlet will display a message to the user, asking the user to log on. If the user is logged on, the portlet will instead display the user's login name.
You will also accomplish the dynamic functionality by using methods included in the portlet JSP base class. All portlet JSPs should extend com.beasys.commerce.portal.admin.PortalJspBase.This class contains many convenience methods which perform general tasks for your portlet JSP page, such as accessing session information and user login information. To achieve this, begin your portlet JSP files with the following line:
<%@ page
extends="com.beasys.commerce.portal.admin.PortalJspBase"%>
Once you have extended PortalJSPBase, you have access to many methods from your JSP file, including getLoggedIn() and getSessionValue(). Instead of explaining exactly what these methods do here, look instead at the following JSP fragment
isloggedon.jsp
<%@ page extends="com.beasys.commerce.portal.admin.PortalJspBase"
%>
<p>
<%
// getLoggedIn() returns true if the user is logged in
if ( getLoggedIn(request) )
{
%>
You are currently logged in as
<%= getSessionValue(
com.beasys.commerce.axiom.jsp.JspConstants.SERVICEMANAGER_USER,
request)
%>
. Please make yourself at home.
<%
}
else
{
%>
You are not currently logged on. Please click the
key icon at the top right-hand corner of the page to
log onto this site.
<%
}
%>
</p>
This code is the complete text for your first dynamic portlet.
To implement this project, follow these steps:
You have now finished your first dynamic portlet.
Project 7: Building a Second Dynamic Portlet
In project 6, you built a simple dynamic portlet using functionality provided by extending PortalJSPBase. Take some time to look at other functionality provided by PortalJSPBase. Once you have done this, you are ready to begin working with another dynamic technique available to your JavaServer Page portlets, JSP tags.
Included with the WebLogic Personalization Server is a set of tag libraries that enable your JSPs access to the full power of the personalization engine. The five tag libraries are as follows:
For more information, see JSP Tag Library Reference. For full details on how tag libraries work in the JSP language, consult a JavaServer Page handbook. After viewing this sample tag library portlet, you will see that tag libraries are quite easy to use.
Each one of these tag libraries supports a number of tags. In this project, you will use tags from the User Management and Personalization Utilities tag libraries. This portlet will output the name of all users of your portal. Next to each username, it will output the e-mail address of that user. A detailed description of how this code works is not provided here. Hopefully, reading the code and consulting the WebLogic Personalization Server Developer's Guide is sufficient.
One point about the code should be made. You will notice that for every username retrieved by calling <um:getUsersnames>, there is a call to <um:getProfile>. It is necessary to explain why this line of code is needed. At any time during the processing of a portlet, exactly one user profile is in scope. Calls like <um:getProperty> and <um:setProperty> refer to the user profile in scope. In this project the code must iterate through the list of usernames and query the profile associated with each user. Therefore, before a call to <um:getProperty> is made, the profile for the user must be loaded into scope by calling <um:getProfile>. And at the end of this JSP, the original user profile must be loaded back into scope to avoid causing problems with other portlets.
EmailList.jsp
<%-- include the tag libraries we need --%>
<%@ taglib uri="es.tld" prefix="es" %>
<%@ taglib uri="um.tld" prefix="um" %>
<%-- extend PortalJSPBase to get some base functionality --%>
<%@ page
extends="com.beasys.commerce.portal.admin.PortalJspBase"
%>
<%
// get the name of the current user
String originalUserName = (String)getSessionValue(
com.beasys.commerce.axiom.jsp.JspConstants.SERVICEMANAGER_USER,
request);
if ( originalUserName == null ) originalUserName = "";
// get the name of the portal
String portalName =
(String)getSessionValue(PORTAL_NAME, request);
if ( portalName == null ) portalName = "";
%>
<%-- ask WLCS to put a list of the user names in string array "userNameList" --%>
<um:getUsernames id="userNameList" result="namesResult"/>
<table border=1 cellspacing=1 align="center">
<tr>
<th colspan=2>Portal Users</th>
</tr>
<es:forEachInArray id="curUser" type="String"
array="<%=userNameList%>"
counterId="curIndex">
<tr>
<%-- This section is evaluated once for
every user in userNameList --%>
<%-- Output the name of the user for this row --%>
<td><%=curUser%></td>
<%-- Output the email address of the curUser --%>
<td>
<um:getProfile profileKey="<%=curUser%>"
scope="request"
/>
<um:getProperty id="email"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_EMAIL%>"
/>
<%=email%>
</td>
</tr>
</es:forEachInArray>
<%
if (getLoggedIn(request)) {
%>
<um:getProfile
profileKey="<%=originalUserName%>" scope="request" />
<%
}
%>
</table>
This code is the complete text for your second dynamic portlet.
To implement this project, follow these steps:
Click Create, then click Back. You have now successfully registered your new portlet with the server.
You have now seen the three major techniques for building a portlet: static HTML, dynamic behavior based on extending PortalJSPBase, and dynamic behavior based on the WebLogic Personalization Server tag libraries.
Advanced Portlet Functionality
In the previous section, you learned how to build portlets. This section continues with portlets and demonstrates how to use more portlet features.
Project 8: Adding a Maximized URL
This project will walk you through how to build a maximized version of your portlet. In the default case, your portlet cannot be maximized. If you allow your portlet to be maximized but do not provide a maximized URL, WebLogic Personalization Server will simply use your normal-sized portlet content when maximized. In most cases, you will want to take advantage of the extra space afforded by being maximized and alter your portlet content to include more information. This project shows how to do this. It assumes you completed "Project 7: Building a Second Dynamic Portlet". You will not change the portlet created in that project, but you will add a new maximized JSP.
The first step of this project is to create the new portlet content JSP for the maximized state. Since in the maximized state your portlet has more screen real estate, you can display more information. In this case, for each user displayed, you will show more columns of information. The following is the maximized JSP:
EmailListMax.jsp
<%-- include the tag libraries we need --%>
<%@ taglib uri="es.tld" prefix="es" %>
<%@ taglib uri="um.tld" prefix="um" %>
<%-- extend PortalJSPBase to get some base functionality --%>
<%@ page
extends="com.beasys.commerce.portal.admin.PortalJspBase"
%>
<%
// get the name of the current user
String originalUserName = (String)getSessionValue(
com.beasys.commerce.axiom.jsp.JspConstants.SERVICEMANAGER_USER,
request);
if ( originalUserName == null ) originalUserName = "";
// get the name of the portal
String portalName =
(String)getSessionValue(PORTAL_NAME,request);
if ( portalName == null ) portalName = "";
%>
<%-- ask WLCS to put a list of the user names in
string array "userNameList" --%>
<um:getUsernames id="userNameList" result="listresult" />
<table border=1 cellspacing=1 align="center">
<tr>
<th colspan=7>Portal Users</th>
</tr>
<es:forEachInArray id="curUser" type="String"
array="<%=userNameList%>" counterId="curIndex">
<tr>
<%-- This section is evaluated once for
every user in userNameList --%>
<%-- Output the name of the user for this row --%>
<td><%=curUser%></td>
<um:getProfile profileKey="<%=curUser%>" scope="request" />
<%-- Output the email address of the curUser --%>
<td>
<%-- Load curUser's profile into scope -->
<um:getProperty id="email"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_EMAIL%>"/>
<%=email%>
</td>
<%-- Output the first name of the curUser --%>
<td>
<um:getProperty id="first"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_FIRST%>"/>
<%=first%>
</td>
<%-- Output the last name of the curUser --%>
<td>
<um:getProperty id="last"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_LAST%>"/>
<%=last%>
</td>
<%-- Output the address of the curUser --%>
<td>
<um:getProperty id="address"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_ADDRESS%>"/>
<%=address%>
</td>
<%-- Output the city of the curUser --%>
<td>
<um:getProperty id="city"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_CITY%>"/>
<%=city%>
</td>
<%-- Output the state of the curUser --%>
<td>
<um:getProperty id="state"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_STATE%>"/>
<%=state%>
</td>
<%-- Output the zip code of the curUser --%>
<td>
<um:getProperty id="zip"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_ZIP%>"/>
<%=zip%>
</td>
</tr>
</es:forEachInArray>
<%
if (getLoggedIn(request)) {
%>
<um:getProfile profileKey="<%=originalUserName%>"
scope="request" />
<%
}
%>
</table>
To specify the above code as your maximized portlet content, follow these steps:
Click Save, then click Back.
Note: Remember to log out and log in to force the server to rebuild the portal page.
Project 9: Changing the Look of a Maximized Portlet
Project 9 assumes that you have completed "Project 8: Adding a Maximized URL." The goal of this example is to specify a non-default header and footer to be used when your portlet is maximized. In Project 8, the portlet used the provided alternateheader.jsp and alternatefooter.jsp since you did not override the defaults. In some cases the defaults are sufficient, but for the purposes of demonstration this project will define its own.
EmailListMaxHeader.jsp
<p>
<h1>Email List Portlet</h1>
<hr/>
</p>
EmailListMaxFooter.jsp
<p>
<hr/>
<i>Creating a Custom Portal</i> Tutorial
</p>
These code examples are just simple samples. You may elaborate on the design if you wish.
To replace the alternate header and footer with the code above, follow these steps:
Note: Be sure to create these files in your portal's root folder and not in your portlets subfolder.
Click Save, then click Back.
Note: Remember to log in and log out to force the server to rebuild the portal page.
This concludes the customization of your portlet's maximized state. You may also experiment with creating an editable version of your portlet, and even a help window associated with your portlet.
Project 10: Inter-portlet Communication
In some instances, you will want to have actions in one portlet affect the display of another portlet. This is called inter-portlet communication. To implement this functionality, imagine writing Java Beans or database calls where one portlet persists data and another reads the data. This would work, but requires more effort than necessary. Unless you need to pass large amounts of data between portlets, you should follow a simpler approach. This approach is demonstrated here.
Before you read the code, you must understand that there is an object that is shared between the Portal Framework and all of the portlets. This object can be used to pass data between all of these entities. This object is the HTTP request. You may set parameters in the request in one portlet, then forward the request back to the portal, which will ultimately forward the request to all portlets. The end result is that the HTTP request can serve as a message passing mechanism for portlets. This project shows you how to exploit this.
The goal of this project is to create two portlets. The first portlet, called "User Index," displays a ranges of usernames in the system. For example, it will show "Allan to Carl, Chuck to Elmer, Francis to Irene,..." If the user clicks on a name range, the second portlet will refresh and show detailed information about each username in that range. The second portlet is called "User Index Details."
The following is the code for both portlets. Take special note of how the "href" is constructed in UserIndex.jsp, and how the parameters are retrieved in UserIndexDetails.jsp.
UserIndex.jsp
<%-- include the tag libraries we need --%>
<%@ taglib uri="es.tld" prefix="es" %>
<%@ taglib uri="um.tld" prefix="um" %>
<%-- extend PortalJSPBase to get some base functionality --%>
<%@ page
extends="com.beasys.commerce.portal.admin.PortalJspBase"%>
<%
// get the name of the current user
String originalUserName = (String)getSessionValue(
com.beasys.commerce.axiom.jsp.JspConstants.SERVICEMANAGER_USER,
request);
if ( originalUserName == null ) originalUserName = "";
// get the name of the portal
String portalName = (String)getSessionValue(PORTAL_NAME,
request);
if ( portalName == null ) portalName = "";
%>
<%-- ask WLCS to put a list of the user names in string
array "userNameList" --%>
<um:getUsernames id="userNameList" result="listresult" />
<table border=1 cellspacing=1 align="center">
<tr>
<th>Portal Users Index</th>
</tr>
<%
int divisor = 5;
boolean isRowTerminated = true;
String persistCurUser = null;
%>
<es:forEachInArray id="curUser" type="String"
array="<%=userNameList%>" counterId="curIndex">
<%-- This section is evaluated once for every user in
userNameList --%>
<%
persistCurUser = curUser;
// start the cell if this is the first user in a range
if (curIndex.intValue()%divisor == 0)
{
// beginning of range
isRowTerminated = false;
%>
<%-- THIS IS WHERE THE DATA IS PASSED --%>
<tr><td>
<a href="<%=response.encodeURL(createURL(request,
getHomePage(request),
("userIndexStartIndex=" + curIndex
+ "&userIndexDivisor=" + divisor
)))%>"
>
<%=curUser%> to
<%
}
// finish cell if this is the last user in range or
// the last user in the list
if (curIndex.intValue()%divisor == divisor-1)
{
// end of range
isRowTerminated = true;
%>
<%-- Output the name of the user for this row --%>
<%=curUser%></a></td></tr>
<%
}
%>
</es:forEachInArray>
<%
if (!isRowTerminated)
{
// terminate the row if it ended on a
// non-divisor boundary
%>
<%-- Output the name of the user for this row --%>
<%=persistCurUser%></a></td></tr>
<%
}
%>
</table>
UserIndexDetails.jsp
<%-- include the tag libraries we need --%>
<%@ taglib uri="es.tld" prefix="es" %>
<%@ taglib uri="um.tld" prefix="um" %>
<%-- extend PortalJSPBase to get some base functionality --%>
<%@ page extends="com.beasys.commerce.portal.admin.PortalJspBase"%>
<%
// get the name of the current user
String originalUserName = (String)getSessionValue(
com.beasys.commerce.axiom.jsp.JspConstants.SERVICEMANAGER_USER,
request);
if ( originalUserName == null ) originalUserName = "";
// get the name of the portal
String portalName =
(String)getSessionValue(PORTAL_NAME, request);
if ( portalName == null ) portalName = "";
%>
<%
// GET THE PARAMETERS PASSED IN, if they exist
int startIndex = 0;
String startIndexString =
request.getParameter("userIndexStartIndex");
if (startIndexString != null)
{
try
{
startIndex =
Integer.parseInt(startIndexString);
}
catch (Exception e) {
System.out.println("UserIndexDetail.jsp - "+
"startIndex parse error: "+ startIndexString);
}
}
int divisor = 0;
String divisorString =
request.getParameter("userIndexDivisor");
if (divisorString != null)
{
try
{
divisor = Integer.parseInt(divisorString);
}
catch (Exception e) {
System.out.println("UserIndexDetail.jsp - "+
" divisor parse error: "+ divisorString);
}
}
if (divisor == 0)
{
%>
Click a name range in the User Index portlet to display
information about each user in the range.
<%
}
else // divisor !=0
{
%>
<%-- ask WLCS to put a list of the user names in string array
"userNameList" --%>
<um:getUsernames id="userNameList" result="listresult" />
<table border=1 cellspacing=1 align="center">
<tr>
<th colspan=2>Portal Users</th>
</tr>
<es:forEachInArray id="curUser" type="String"
array="<%=userNameList%>" counterId="curIndex">
<%
if ((curIndex.intValue() >= startIndex) &&
(curIndex.intValue() < startIndex+divisor))
{
%>
<tr>
<%-- This section is evaluated once for every user in
userNameList --%>
<%-- Output the name of the user for this row --%>
<td><%=curUser%></td>
<%-- Output the email address of the curUser --%>
<td>
<um:getProfile profileKey="<%=curUser%>"
scope="request" />
<um:getProperty id="email"
propertySet="<%=portalName%>"
propertyName="<%=PROFILE_EMAIL%>"
/>
<%=email%>
</td>
</tr>
<%
}
%>
</es:forEachInArray>
<%
if (getLoggedIn(request)) {
%>
<um:getProfile profileKey="<%=originalUserName%>"
scope="request" />
<%
}
} // from else clause of if (divisor == 0)
%>
</table>
To use the above code as your portlets, follow these steps:
Click Create. You have now successfully registered your first new portlet with the server.
Click Create. You have now successfully registered your second new portlet with the server.
You have now completed the advanced portlet creation projects.
Using the HTTP request method to communicate between portlets
There are two issues that you should be aware of when using the HTTP request method to communicate between portlets.
Parameter name collisions between portlets
Because the HTTP request is broadcast to all portlets within the portal, you must be careful to avoid a parameter name collision between portlets. For example, suppose a portlet appends a URL parameter such as src=/usr/local/src to the anchor tags that it generates. If other portlets look for such a parameter, then they will all find it when the user clicks the link. Unless all portlets looking for that parameter are interpreting it the same way, confusing or bad parameters can be passed to the receiving portlets.
To avoid name collisions, remember that the URL parameter names that get encoded by using the URL string are global in nature.
Several sets of portlets using the HTTP request method at once
When a set of portlets communicates, the code does the following:
<a href="<%response.encodeURL(createURL(request, getHomePage(request),...and so on.
When the getHomePage()method is called, it strips off any parameters that were passed in from the last request. This is desirable when a single set of portlets communicates using this method. However, if an unrelated set of portlets is employing the same technique, then only one set can be "active" at any one time.
For example, one set of portlets (group A) includes a headline browser portlet and a news story display portlet. When a user clicks a headline, the headline browser uses the code above to generate a URL. The URL includes a parameter that tells the story display portlet where to find the story. When these are the only two portlets using this method, it works correctly.
Now lets add a second set of portlets to the example. Portlet group B includes a stock quote portlet and a stock detail portlet.When a user clicks a stock quote, the portlet uses the code above to generate a URL. The URL includes a parameter that tells its partner portlet where to find the stock details. Again, this method works correctly when just one set of portlets is communicating. However, what happens when both sets of portlets are using the getHomePage()method?
In this scenario, first the user clicks a story headline to see the story. The story portlet reads the parameter from the URL and displays the story. Then the user clicks a stock symbol to get detailed stock information, and the stock quote portlet generates a new anchor tag using a stock related parameter. The stock details display in the partner stock portlet just fine, but what happens in the story portlet?
When the user clicks the stock symbol, this second event notifies all the portlets to poll again. The URL generated by the stock quote portlet overwrote the news story parameter with its own stock related parameter, and so the new URL contains no parameters related to the story. If the story portlet does not find the parameter it expects, it may just display a blank portlet page. You can easily avoid this problem using the session cache. If the story portlet has already seen a parameter telling it where to find the story, it could use the session cache to default to the previous story location if there is no new information.
Other Customization Techniques
This tutorial has introduced you to the power of WebLogic Personalization Server and the Portal Framework. With the techniques described in the previous sections, you can now build a sophisticated portal.
However, there are more ways in which you can build your customized application. Although this chapter will not cover these additional techniques in detail, this section discusses each technique and provides pointers to other documentation that contains more information.
More Portlet Customization
In Projects 8 and 9, you created a maximized version of your portlet. In the same manner, you may create an editable version of your portlet. You may also specify a help page for your portlet, mandate that it appear for all users, allow/disallow it to be minimized, make it floatable, and make changes to the title bar appearance.
For more information, about the Portal Management administration tools, see Creating and Managing Portals in the WebLogic Personalization Server User's Guide.
Database Interaction
In many cases you will want to persist data or retrieve persisted data from within your portal and portlets. In most cases, you will be using a database for this purpose. WebLogic Personalization Server provides simple connectivity with your database via Personalization Utility tags. Specifically, refer to the <es:preparedStatement> and <es:simpleReport> tags.
For more information, see Personalization Utilities.
Alternatively, enterprise applications will likely want to use Enterprise Java Beans for data persistence. WebLogic Commerce Server provides full support for the EJB specification.
For more information, consult the WebLogic Server documentation.
Java Beans Interaction
The Java Beans technology provides an easy way to remove the bulk of your code from your JavaServer Page files. This will free your JSP files from clutter, and make that code more maintainable and reusable. WebLogic Commerce Server provides full support for calling Java Beans from your JSP files.
For more information, consult a JavaServer Page handbook.
Personalization Advisor Functionality
The Advisor delivers content to a personalized application based on a set of rules and user profile information. It can retrieve any type of content from a Document Management system and display it in a JSP or use it in a servlet. The Advisor ties together all the services and components in the system to deliver personalized content. The Advisor component includes a JSP tag library and an Advisor EJB (stateless session bean) that access the WebLogic Personalization Server's core personalization services.
For more information, consult Creating Personalized Applications with the Advisor.
Internationalization
WebLogic Personalization Server provides a simple framework that allows access to localized text labels and messages. The internationalization (I18N) framework is accessible from JSP files through a small I18N tag library.
For more information, consult Creating Localized Applications with Internationalization Tags.
Using Webflow
In WebLogic Personalization Server, Webflow is a feature that allows you to string together JSP files, input processors (IPs) and pipeline processors (PPs) without hard coding the linkage between them. Instead, the linkage is defined in an external Webflow properties file.
If you are considering using Webflow within the Portal Framework, see Using Webflow Within a Portal.
Commerce Functionality
The process customers go through when making a purchase from your Web site is one of the most common but complex aspects of an e-business. To help you get to market faster than your competitors, the WebLogic Commerce Server product provides you with an Order Processing package. This package contains default implementations for the most common e-business order-related services (such as shopping cart management, taxation, payment, and so on). Designed to be used out-of-the-box, the Order Processing package allows your site designers to customize the order process without the need for advanced programming skills. Additionally, it is easily extensible for those with advanced technical knowledge.
For more information, consult the Order Processing Package documentation.
Modifying the Portal Framework
In some cases, the Portal Framework may be generally suitable for your needs, but some aspects of it needs to be modified. A valid option in this case is to actually modify the JSP files in the repository folder. You are encouraged to use the Portal Framework files in any way to help you get to market quickly. Be aware that some changes you make may be inconsistent with the administration tool, therefore you will need to implement your own administration functionality in those cases.
To do this, you will need to read and understand the contents of the JSP files located in the repository folder. Therefore you will need to be comfortable with JSP. Also, you will need to be comfortable with the WebLogic Personalization Server custom JSP tags and provided classes such as PortalJSPBase.
For more information, see JSP Tag Library Reference.
Building Your Site Without the Portal Framework
You may not want a portal metaphor when creating your site. Or, you may find that your site design would require extensive changes to the Portal Framework. In both cases, you may choose to build your site from scratch. In this case, you have the full power of JSP and HTML at your disposal, as well as the commerce components (shopping cart management, taxation, payment) and the personalization components (rules, property sets, content management, user and group management) via the JSP tag libraries.
For more information, see JSP Tag Library Reference.
Framework Files
The following table displays the names and functions of the template JSP files provided with the WebLogic Personalization Server framework. Each of these files is located in the root directory of the portal which it serves, such as /portals/repository.
![]() |
![]() |
![]() |
|
Copyright © 2000 BEA Systems, Inc. All rights reserved.
|