Articles
Java Platform, Enterprise Edition
|
| By Rick Palkovic and Mark Basler, September 2006 |
|
| |
This is the first in a short series of articles that add Ajax functionality to a Java EE NetBeans project. Through the articles, you will see how to implement increasingly sophisticated Ajax implementations.
Ajax is a combination of existing technologies rather than a technology in itself. It combines, at a minimum, JavaScript, XML, HTML, and their related technologies such as Cascading Style Sheets (CSS) and Document Object Model (DOM).
|
Learn About Ajax
For background information about Ajax and strategies for implementation, see Ajax Design Strategies by Ed Ort and Mark Basler. |
|
Ajax techniques can exchange data asynchronously between a client web application and a web or application server, thus making the user experience more responsive. To that end, Ajax-enabled client applications typically use the
XMLHttpRequest object to request data from the application server.
Because Ajax relies on several underlying technologies and is not a clearly defined technology itself, there are many ways to implement its functionality. This series of articles uses a single example application to describe several of the most popular and productive approaches, beginning with the most basic. One good source of information about Ajax is the article Ajax Design Strategies. That article provides information about the tradeoffs among various approaches to implementing Ajax.
To get the most out of this article, you should be familiar with the NetBeans IDE and the Java EE 5 tutorial .
The application used in these articles is derived from the Duke's Bookstore application, included in the Java EE 5 tutorial. The application has been extracted from the tutorial for use in this article.
| |
This article is based on the premise that, as a developer, you want to add informational pop-up balloons to books listed in the catalog of Duke's Bookstore. The pop-up balloons will appear when a user's mouse pointer hovers over a catalog entry.
There are several ways to add this feature, of course. The following table compares some alternatives and highlights the tradeoffs. (Similar comparisons can be found elsewhere — at ajax info, for example.)
| Technology | Pros | Cons |
|---|---|---|
| Conventional HTML |
|
|
| Applet |
|
|
| Adobe (formerly Macromedia) Flash |
|
|
| Java WebStart |
|
|
| DHTML |
|
|
| DHTML with Hidden iFrame |
|
|
| Ajax |
|
|
After comparing alternative technologies, the balance of pros and cons tilts in favor of Ajax for your application. The arguments against using Ajax — user's loss of context and difficulty in programming — are not objectionable. First, because the pop-up balloons you plan don't persist on the page, your users will be able to return to a bookmarked page without confusion. Second, you plan to use features in the NetBeans IDE that will simplify programming and deployment.
| |
Your first approach to implementing the feature is to add the Ajax-based pop-up balloons to your application directly. You write supporting JavaScript and CSS files and fulfill the Ajax request by writing a servlet in Java. You integrate these files with the existing JavaServer Pages (JSP) files in the NetBeans project. This approach is the most direct model for adding Ajax to a legacy application. However, it might not be the easiest to program.
To understand the architecture of this approach, consult the brief discussion in Ajax Design Strategies.
To follow along with remainder of this article, you will need to download the example application and the necessary tools. If they are not installed on your local system, download and install them now, using the installation instructions on the download pages.
In the rest of this article, the installed location of your GlassFish application server will be denoted by
server, and the installed location of the Duke's Bookstore project will be denoted by
project. Your installation directory trees should look like the following figure. In this case, the value of
server would be
C:/glassfish, and the value of
project would be
C:/bookstore.
Figure 1: Server and Project Installation Directories
|
You must edit the file that defines build properties to customize it for your environment. These build properties are used by the
ant scripts that build the project.
To edit the
build.properties file:
/examples/bp-project/build.properties
|
for example:
|
Editing these two lines should be sufficient for most default installations. The following table shows how to set other values, if necessary. If you need more help, consult these instructions for tutorial installations.
| Property Name | Description | Examples |
javaee.home
|
The installation directory of the GlassFish application server | c:/glassfish
|
javaee.server.name
|
Host name of the the GlassFish application server | localhost
|
javaee.server.port
|
The port number you chose while installing the GlassFish application server | 8080
|
javaee.server.username
|
The administrator username specified while installing the GlassFish application server | admin
|
javaee.server.passwordfile
|
The path to a file containing the administrator password for the GlassFish application server. The password file needs to be in the following format:
Where you will replace admin-password with the admin password for the GlassFish application server. |
c:/bookstore/examples/
|
javaee.adminserver.port
|
The port number you chose while installing the GlassFish application server | 4848
|
proxy.host
|
The host name of your HTTP proxy server, if the GlassFish application server is behind a firewall. Leave blank otherwise. | myproxy.mydomain
|
proxy.port
|
The port number of your HTTP proxy server, if the GlassFish application server is behind a firewall. Leave blank otherwise. | 8080
|
Next, start the server's database and domain to prepare it for the application deployment.
javadb database by typing the following command:
server
|
server
|
Next, create database tables. This step is needed to set up the database and
jdbc resource in
javadb and the GlassFish server.
|
To register the GlassFish server so that it can be used with the NetBeans IDE:
|
admin Password:
adminadmin
Figure 2: Server Manager Window
|
Next, open the project in the NetBeans IDE:
/examples/web/bookstore2. Select the bookstore2 project folder and click Open Project Folder. The IDE opens the project folder and selects bookstore2 as the main project. Note that the bookstore project is also opened because bookstore2 depends on many of the files in bookstore.
/glassfish/lib directory. Select the
javaee.jar file and open it. Click Close to resolve the reference and close the window.
You can now build and deploy the bookstore2 project.
In the NetBeans Projects window, the bookstore2 project should be shown in bold type to indicate that it is the main project. If it is not, set it as the main project by choosing Files > Set Main Project > bookstore2.
The status of the build is shown in the NetBeans Output window. When the build finishes successfully, your browser opens to show the Duke's Bookstore application. Clicking on the Start Shopping link will take you to the catalog page, shown below.
Figure 3: Duke's Bookstore, Catalog Page
|
| |
From the Duke's Bookstore catalog page, shown in the previous figure, you can click one of the book links. Clicking a link opens a new page with detailed information about the book, as shown in the following figure.
Figure 4: Duke's Bookstore, Detail Page
|
Users would have easier access to this information if it could be displayed in a pop-up balloon when a user rolled over the link in the catalog page. You will now implement this feature with Ajax. In your implementation, the entire page will not need to reload to show the information. Only the information in the pop-up balloon loads when the user mouses over the link. The following figure shows the Ajax-enabled page.
Figure 5: Duke's Bookstore, with Pop-up Balloon
|
| |
Your first approach to adding the Ajax pop-up balloon to the application is the most basic: you will hand-code a JavaScript (
.js) file and a cascading style sheet (
.css) file for the client. To handle the client requests on the server, you hand-code a Java servlet (
.java). You also edit the project's
bookcatalog.jsp file.
To save you time, these files have been provided for you. They are already in the project directory, and can be found at the following locations:
project
/examples/web/bookstore2/web/popup.js
project
/examples/web/bookstore2/web/popup.css
project
/examples/web/bookstore2/web/books/bookstore/bookcatalog.jsp
project
/examples/web/bookstore2/src/java/com/sun/bookstore2/dispatcher/PopupServlet.java
Now, examine each of these files to see how they were created.
The
popup.js file provides the JavaScript functions that cause the pop-up balloon to appear. Note that the code in this file code was developed following the
JavaScript Recommendations for Ajax Component Writers.
To examine the
popup.js file in the IDE:
popup.js. The file opens in the NetBeans JavaScript Editor.
|
The opening lines of the file (lines 1-3) create a component namespace object,
bpui. The name is used in the
Java Blueprints Solutions Catalog, and stands for “blueprints user interface.” Using the namespace as a prefix is good programming practice because it helps ensure that functions will have unique names. For example, if you simply defined
showPopup() as a function instead of
bpui.alone.showPopup(), then there could be a conflict with another
showPopup() function. The last such function that is defined in a file takes precedence over all earlier functions.
In line 7, you create a
bpui.alone object to hold the pop-up balloon.
In line 8, you create a
bpui.alone.timeout timeout variable in the object. The timeout is used as follows.
When a user mouses over a book link in the catalog page, a timer begins counting. If the mouse is still hovering over the link after a timeout period of 1000 ms has elapsed, an
XMLHttpRequest request is sent to the server. If the server responds with the necessary pop-up balloon data before the timeout has expired, the balloon is hidden until the end of the timeout. If the server is slow and does not respond until after the timeout, one of two conditions applies:
Line 9 creates a
bpui.alone.req object to hold the request.
The function
bpui.alone.showPopup() (beginning on line 12) is called when the user mouses over a link. The function sets the location for the pop-up balloon and then sets the timer to begin counting. After the timeout period has elapsed, the
bpui.alone.showPopupInternal() function is called.
The function
bpui.alone.showPopupInternal() (beginning on 32) initiates the Ajax
XMLHttpRequest request.
Because your Ajax implementation will use a servlet to respond to client requests, your
popup.js file uses the following line to set the
URL:
url="../PopupServlet?bookId=" + escape(bookId); |
The servlet mapping is defined in the web deployment descriptor file,
web.xml, which is stored in the following location:
project
/examples/web/bookstore2/build/web/WEB-INF/web.xml
Note that another line, commented out in
popup.js, can be used to set the URL:
// url="../book_lookup.jsp?bookId=" + escape(bookId); |
When this line is uncommented, it sets a JSP page as the dispatcher. You enable this line later when you explore the JSP approach. For now, leave the line as a comment.
The function then concatenates the Ajax dispatcher URL with the bookId (line 40) and sets the pop-up balloon's Ajax callback function (line 41).
The statement at line 42 specifies that the
XMLHttpRequest object uses a
GET method (as opposed to a
POST method) to communicate with the server-side component. The
url parameter indentifies the URL of the server-side component, which was set to
PopupServlet in the previous statement. The parameter
true indicates that the communication is asynchronous.
Finally, the function sends the request (line 43).
The callback function
ajaxReturnFunction() (beginning on line 46) accepts the server response. The function checks the validity of the request's response by making sure that the ready state is
complete (
readyState property equals 4) and the response is
OK (
status property equals 200). For details about how to work with Ajax
XMLHttpRequest objects, click
here.
The function then extracts the document root of the
XML response and parses it. The function
document.getElementById() (lines 55–56) inserts the information into the appropriate nodes of the
DOM in the
JSP. Note the
innerHTML property, which is used to insert an HTML fragment. Using the
innerHTML property to update the DOM avoids the need to create each element in the object individually with conventional DOM
API functions.
The last line of the
if clause (line 58) sets the value for the visibility style of the pop-up balloon to
visible. The initial style is set to
hidden in the
popup.css file, which is explained in the following section.
The
bpui.alone.hidePopup() function (beginning on line 65) is called on mouseout to hide the pop-up balloon and clear the
timeout variable.
In the do-it-yourself approach to Ajax described here, you must provide a cascading style sheet (
.css file) that describes the appearance of the pop-up balloon. In this project, the
popup.css file describes the layout for the balloon, including its fonts, colors, and dimensions. The
bookcatalog.jsp file uses these descriptions to build the pop-up balloon as it inserts content.
To view the
popup.css file in the IDE, double-click the bookstore2 > web > popup.css node in the Files window, just as you did for the
popup.js file.
The file begins by defining seven class styles that are used to set the pop-up balloon's border widths and colors, its background color, and the margins within which the text content of the balloon appears. The class styles also specify the images used to produce rounded corner effects for the pop-up balloon. In each square corner image, the outside corners are white, and the inside corners are transparent to allow the balloon's border color to show through.
Following these definitions is another class style definition,
div.bpui_alone_popup, that is used with the block-level container tag
<div>. This class is also used to format the balloon's content.
To learn more about CSS, consult one of the many online resources available, such as W3 Schools.
By examining the
bookcatalog.jsp file, you learn how the
popup.js and
popup.css files produce a pop-up balloon.
bookcatalog.jsp file.
bookcatalog_orig.jsp. This file is the original version of the file, which does not produce pop-up balloons.
bookcatalog_popup.jsp, right-click, and choose Rename from the context menu. Change the name to
bookcatalog.jsp.
bookcatalog.jsp to view the file in the NetBeans Editor.
The original and pop-up versions of the file are nearly identical except for the code between the comment lines at line 28 and line 57:
<!-- BEGIN: popup --> |
and
<!-- END: popup --> |
The first two lines (29–30) provide the links to the
popup.js and
popup.css files:
<script type="text/javascript" src="../popup.js"></script>
|
As discussed earlier, the
popup.css file provides the presentation layout styles for the pop-up balloon. The code following these links (lines 33–56) makes use of the CSS styles and HTML to draw the balloon and insert content into it.
The remainder of the file is identical to the original
bookcatalog.jsp file, with one exception. Embedded in the layout table for the page, in lines 100–104, are event handlers that call JavaScript functions from
popup.js when the user mouses over or mouses out of a book title link.
<!-- added event handlers to trigger popup -->
|
The following clause triggers the pop-up balloon:
onmouseover="bpui.alone.showPopup(event, '${bookId}')"
|
The value of
${bookId} determines the data that is returned from the server in response to the Ajax
XMLHttpRequest.
The following clause hides the pop-up balloon:
onmouseout="bpui.alone.hidePopup()" |
The pop-up balloon's show and hide functions can be placed elsewhere. Here, they are placed directly following code that provides the value for
${bookId}, which the
onmouseover() function uses to retrieve book information.
With the JavaScript,
CSS, and book catalog
JSP files prepared, all you need to implement your Ajax pop-up balloons is a servlet or server-side component to handle the
XMLHttpRequest. The most hands-on approach to implementing a dispatcher is to write a servlet.
An example of such a servlet is provided for you at
project
/examples/web/bookstore2/src/java/com/sun/bookstore2/dispatcher/PopupServlet.java
View the file in the IDE by opening the bookstore2 > src > java> com > sun > bookstore2 > Dispatcher node and double-clicking PopupServlet.java. The file opens in the NetBeans Java Editor.
Note that nothing in the servlet is unique to Ajax. The servlet composes an XML response to a client request, and is unaware of the asynchronous nature of the request.
The client obtains information for a book by sending a request that contains a bookID. The PopupServlet responds by pulling a Book object from the server-side database, extracting the necessary information, constructing an XML file, and returning the XML file to the client. In the client, the JavaScript callback function,
bpui.alone.ajaxReturnFunction(), handles the response.
This file was created in the NetBeans IDE. Therefore, it extends the standard HTTP servlet (line 24):
public class PopupServlet extends HttpServlet {
|
All requests and responses are forwarded to the method on line 30:
protected void processRequest(HttpServletRequest request, HttpServletResponse response) |
In this method, you set the return type:
response.setContentType("text/xml;charset=UTF-8");
|
You get the response writer from the response itself (line 32), which provides a stream to write the data. Line 33 is from the original bookstore application:
BookstoreMessages messages=new BookstoreMessages(); |
The
messages object contains the data you want to display in the pop-up balloon. The developers of the application used mnemonics to identify parts of each message. For internationalization (i18n) reasons, the mnemonics refer to keys in a properties file. The values of the keys are retrieved and printed. For example, the statement
out.println(messages.getString("Critics"));
|
finds the following line, which is provided by the locale file stored in the
project
/examples/web/bookstore/src/com/sun/bookstore/messages/ directory:
{ "Critics", "Here's what the critics say: " },
|
and prints the phrase
"Here's what the critics say: ". Line 56 does exactly that, together with HTML formatting tags and a description from the database that contains the critics' comments.
As part of the request from the client, the
bookId of the relevant book is passed in. Using the
bookId parameter, the servlet determines the identity of the book to look up.
Because the basic application codes a database object (
BookDBAO) in the servlet context, it is necessary to get the database object from the servlet context in order to retrieve the book information (lines 47 and 48). All of the
bookDBAO functions required are a result of the original bookstore application coding. The
bookDBAO.getBook(bookId) method returns a book object that contains the necessary data.
After the servlet has obtained the data, it composes a response to the request in the series of
out.println() methods (lines 50–66). Note the
CDATA
prefix in the method calls. For example,
out.println("<title><![CDATA[Book Detail]]></title>");
|
The
CDATA prefix is an XML construct that instructs the parser to ignore any XML code in the character string. The prefix allows the payload of the XML elements to be passed to the client application. The complete message is contained between the output
<message> and
</message> tags.
| |
You can generate XML server response with a JSP page rather than a servlet. If you are familiar with JSP programming, you will probably find it much quicker to develop a JSP page than a servlet.
JSP pages show their value in speed of programming, particularly in the NetBeans IDE. If you start your project in the NetBeans IDE, JSP pages are deployed as soon as they are saved, eliminating redeployment and repackaging time. In addition, you can take advantage of the tag library that is associated with JSP technology but is unavailable in a servlet.
The
JSP page that generates the response is named
book_lookup.jsp. It is stored in the
project
/examples/web/bookstore2/web directory. The XML messages that are returned by this JSP page and
PopupServlet described earlier are exactly the same. They are just two ways of generating the same XML response.
Open the file for viewing in the NetBeans Editor by expanding the bookstore2 > web > node in the Files window and double-clicking the
book_lookup.jsp file.
The file contains two scriptlets that provide presentation logic, along with JSP code for the presentation itself. Separating the two activities provides modularity.
The two scriptlets in the file are demarcated by
<% and
%> symbols (lines 9–28 and 40–53).
JSP presentation code lies between the scriptlets (lines 30–38).
Note that in the
JSP code, no message manipulation is required. Message manipulation is handled by the
<fmt> tag library. This code is taken directly from the
bookdetails.jsp file, in the
project
/examples/web/bookstore2/web/books directory. Users who click a book link are routed to a details page. The information on the details page is much like that shown in the pop-up balloon, and the code from the details page is reused for the pop-up balloon.
In summary, if you already have the
JSP file for the details page, you do not need to write a servlet to generate the XML response. Instead, you can use another
JSP file to generate the response, using existing code to describe the presentation, and taking advantage of the
<fmt> tag libraries to format the displayed response.
book_lookup.jsp File
The
popup.js file determines whether to use
PopupServlet or
book_lookup.jsp to serve the client
XMLHttpRequest. To enable
book_lookup.jsp:
url="../book_lookup.jsp?bookId=" + escape(bookId); |
// url="../PopupServlet?bookId=" + escape(bookId); |
Your project builds, deploys, and runs with results identical to those you saw when you used
PopupServlet.java.
| |
In this article, you learned how to hand-code an Ajax feature into a web application that was developed in the NetBeans IDE. You installed and configured the tools you needed to develop and deploy the application: the NetBeans IDE and the GlassFish application server.
You learned how to code the
popup.js,
popup.css, and
bookcatalog.jsp files in the client to generate an
XMLHttpRequest request object. You learned how to write a servlet, deployed on the GlassFish server, that can generate a response to the request.
You then learned how to specify a JavaServer Page on the server instead of a servlet to generate a response.
| |
In the next article in this series, you will use Dojo toolkit libraries to implement the pop-up balloon Ajax feature.
| |