This article introduces you to the idea of integrating Ajax into your portal applications. Because there are several general Ajax articles already available (see Resources), we assume you understand the basics of Ajax; that is, you already know what Ajax means, how it got its name, the fact that it's not new, and how Google brought this technology into the mind set of every executive and technologist on the planet. Our intention is to equip you with useful information related to using Ajax in your portal applications, so when the call comes down from the CTO's office asking if your portal applications are Ajax enabled, you can stand up and say, "You bet!"
So what this article describes are areas to consider if you decide to inject Ajax into your portal. While the focus is on portal applications, these tips are generally applicable to most complex applications. This article also prepares you for a future tutorial, in which we will detail the creation of an Ajax portlet application.
XMLHttpRequest. This class provides a background communication channel to a server and for the resulting response. Everything else, including drag-and-drop, DOM updates, styling, and all the other things that make everyone go "ohh and ahh", is DHTML.
Why Ajax and WebSphere Portal are a good fit
One of the most expensive actions in a portal environment is to refresh the page. When the user clicks a link or takes some other action on the page, the portal processes the
actionPerformed()method for the target portlet and the
doView() methods for each portlet on the page. Then, it aggregates the results and sends the entire HTML document down to the browser.
While caching can reduce a lot of the overhead, there is still a lot going on. You could use Ajax to handle many of the user interaction events in the background, and then to update portions of the page, without requiring a full portal refresh cycle. This technique can vastly improve the end-user experience by increasing the responsiveness of individual actions, and the overall application performance. In certain circumstances, using Ajax can contribute to a cleaner overall architecture of your application. Having a secondary Ajax controller (such as a servlet or Web service) forces a stronger separation of your model code.
When applying a full Ajax controller design to your application, you should let the Ajax controller handle all basic user input actions and segmented display updates. Only use the portal
actionPerformed() method for page-level transitions or to process major state changes.
Why Ajax and WebSphere Portal are not a good fit
So, why would you not want to use this new fangled paradigm in rich internet applications? All the weekly technical magazines insist that this is the way to go, and besides, your boss told you to use it because it's "one of our business goals." OK, we won't tell you not to use it, but we do want you to know about some potential pitfalls:
- Using multiple controllers (for example a portlet, a servlet, and a Web service) adds to the complexity of the application.
- Using Ajax forces a lot of logic to be processed on the client.
- Your application might not require extra data updates to the browser between pages.
So with all that said, you might decide that Ajax isn't for you and you will find another article to read. Wait, that's no fun. Read on, my friend, this stuff is way too cool not to add to your applications.
The bottom line is to take it slow. Find an application that could use a little kick, and add a dash of Ajax to a user form or wizard. Once you get your feet wet and understand how a little effort can produce some effective user enhancements, you will be ready to really add some magic to your portal applications.
When you add Ajax to a portal application, you are effectively adding multiple controllers to the classic MVC pattern. This decision has the potential benefit of forcing a cleaner separation of the model logic. The downsides are the added complexity and the unavoidable requirement to break the controller apart into these three aspects:
- The portlet
- The servlet or Web service
The basic premise of using Ajax in a portal application is the need for a separate controller. Under normal circumstances, you use a servlet to perform the communications with the Ajax client. You can either bundle the servlet with the portlet WAR file or include it as part of a stand-alone Web application.
Figure 1 shows potential Ajax server targets.
- If you bundle the servlet with the portlet WAR file, then you can share session data between the servlet and the portlet. The servlet, portlet, and the model code are tightly coupled.
- If you do not need this level of coupling and the data and logic to be processed by Ajax are not dependent on the portlet, then you can create a stand-alone servlet or Web service to promote reuse.
Figure 1. Ajax server target possibilities
Adding Ajax to a portlet application
To implement Ajax in your portal application, you need to follow a few simple steps. The following discussion assumes that you are bundling your Ajax servlet with your portlet WAR file.
- Create and define the Ajax servlet.
- Implement the Ajax framework.
Create and define the Ajax servlet
The process of bundling a servlet with your portlet WAR file is very straight forward; however, even seasoned portlet developers are not always sure of all the details. So, here are the complete and sordid details.
- Define the servlet in the web.xml file, as in Listing 1
- Include the servlet JAR file or classes.
Listing 1. Servlet mapping in the web.xml
<servlet> <servlet-name>MyAjaxServlet</servlet-name> <display-name>MyAjaxServlet</display-name> <description></description> <servlet-class> com.ibm.ajax.MyAjaxServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>MyAjaxServlet</servlet-name> <url-pattern>/Ajax</url-pattern> </servlet-mapping>
Listing 2. Global reference to the servlet.
As with any external resource to be added to a portlet page, you must encode the URL and set the base context, as in Listing 3.
Listing 3. Script to encode the URL and set the base context.
?v1.1.2), but any string will work.
Implement the Ajax framework
Making Ajax perform its magic consists of a few boilerplate actions. We give you the overview here. You will see the code description in a future, follow-up tutorial.
- Create a global XMLHttpRequest object variable. Because all communications are asynchronous, you must define a unique variable for each Ajax event.
<input onChange='eventHandlerFunction()' ... >
- Define a function to handle the event; specifically, implement these tasks:
- Instantiate the XMLHttpRequest (
xhr) object variable. Details of this are browser specific, which we will cover in the future tutorial.
- Set the
- Set the servlet, type, and parameters.
xhr.open(), xhr.setRequestHandler(), and xhr.send()
- Instantiate the XMLHttpRequest (
- Define a call-back function to process the communication states and the response data.
- This function handles the various communication state changes, such as when the call starts, when a connection is established, and when the response has been received.
- Processing of the response typically consists of parsing the returned XML (or other contents), and using this data to update the DOM tree.
Figure 2 shows how all the pieces fit together.
Figure 2. AJAX communications event model
Portal specific concerns
There are several issues that you should be aware of when implementing Ajax in a portal application.
// Global XMLHttpRequest variable var <portlet:namespace />xhrFieldsRequest;
If you use an Ajax toolkit, the abstraction layer will resolve any naming conflicts.
Using ID attributes
ID attributes are often used in Ajax to quickly update a portion of the page. Because ID attributes within any HTML tag are global to the DOM, you need to make sure they are unique. If you have duplicate ID attributes, then results are unpredictable but generally not what you want, and the problem can be maddening to track down.
To be safe, namespace all ID attributes, even though doing this can make your code difficult to read, as you can see in Listing 5.
Listing 5. Safely namespacing an ID attribute.
Other state issues that can easily trip you up are the back button and bookmarked URLs. In general, avoid major state changes based on Ajax. Leave that to real portal
Sharing session data
When you bundle a servlet with your portal application, you can share session data between the servlet and portlet. Typically, you want to use Application scope when sharing session data. To the servlet, this is the normal Session scope. To access Portlet scope variables from the servlet requires a special namespaced name value that is based on the portlet's ID that was set when it was originally deployed into a portal. It is very difficult to extract this value during development. Although mostly academic, the syntax of the Portlet scope variables is:
<ID> is the unique identification for the portlet
<NAME> name used to set the object in the Portlet session
Action URLs can be very tricky to deal with when using Ajax. In general, you should not attempt to store Action URLs in the shared session, because they are only valid for the current
doView(). Attempting to use an ActionURL that was stored in the session from a previous
doView() cycle will cause unpredictable results.
An example of when you would want to store Action URLs into the session is an Ajax-driven paging data table that contains Action URL links as part of the data set. When the user clicks Next, the browser generates an Ajax call to the servlet. Then, the servlet extracts the next page of data from the session, and it must have predefined Action URLs. Just be sure that anytime a
doView() call is processed that any session data holding any Action URLs is regenerated.
Portal pages are often very busy, with a lot of aggregated information stuffed onto a single page. Because Ajax calls are performed in the background and they do not trigger the activity icon on the browser, you need to provide a consistent, visual mechanism to inform the user that something is going on. Otherwise, they can get confused and not know that the application is busy processing some action. (We surely don't want confused users.)
You could implement this notification using a floating
DIV section display during activity, or using a simple message on the browser's status bar (although this is considered bad form by some). You could also integrate a custom theme extension that would display a common
Please Wait message for any Ajax-enabled portlet on the page.
In this article, we described how and why you would use Ajax in your portal applications. In a future related tutorial, we will show you how to put all the pieces together to produce an Ajax-enabled database administration tool. Stay tuned.
- Introduction to Ajax on DeveloperWorks
- Ajax Patterns
- Mozilla Developer Center
- Ajax in Action
- Dynamic HTML, The Definitive Guide, O'Reilly
- Build enterprise SOA Ajax clients with the Dojo toolkit and JSON-RPC