Developer: J2EE
"Hello Ajax"! How to Do the Ajax Thing with Oracle JDeveloper
by Frank Nimphius
Get an introduction to Ajax programming by creating a simple "Hello World".
Published May 2006
For sure, the world's most successful computer program is "hello
world". Translations of it are available in almost every programming
language and pattern.
"Ajax"
is a community acronym used by the software industry for a set of
related Web browser technologies, which, in combination deliver the rich
client user experience for Web applications. The promise of Ajax is to
close the usability gap that currently exist between browser based web
applications and existing client-server desktop applications. In this article you'll learn how to translate "hello world" into Ajax, going from simple
to more advanced in small steps.
About Ajax
"Ajax" stands for Asynchronous Javascript and
XML and is the heart of the "Web 2.0" paradigm. By one definition (there are several), Web 2.0 is shorthand for a new generation of Web applications that offer increased responsiveness and richness of UI
components, moving Web applications closer to what users experience
with client-server desktop clients. Ajax is not a software standard but
rather describes of a set of technologies—including JavaScript, the Document
Object Model (DOM), and the browser XmlHttpRequest object (XmlHttp object
in IE)—that are used in combination to build interactive, browser-based
user interfaces.
Because of the browser XmlHttpRequest object, Ajax applications
can use asynchronous communication to retrieve data from the server. There
is no 100 %-clear definition of what makes a Web application "Ajaxian."
Therefore, the best way to look at Ajax is as a programming pattern to
build the next generation of Web applications that bring us closer to
what end users know from their client-server desktop clients. It is important
to note that Ajax is not bound or related to J2EE and Java; rather, it
can be used with .NET, PHP, CGI, and Perl as well. The good news about
Ajax is that it doesn't require an example more complex than "hello
world" to explain its principles.
This how-to provides you with a first-class, hands-on experience for building
an Ajax type of application in J2EE with Oracle JDeveloper.
The technologies used within the exercises are:
- JavaScript - The JavaScript language executes on
the browser client and is in the core of Ajax. You use JavaScript to
perform logical, mathematical and functional operations on the client
side. Using The Document Object Model (DOM), JavaScript can be used
to dynamically manipulate a Web page displayed in the browser.
- Document Object Model (DOM) - A virtual tree representation
of a HTML page document that is kept in the browser memory where
it can be accessed using JavaScript. The DOM tree can be used to dynamically
manipulate UI components of the current HTML page in the browser.
- XmlHttpRequest - The XmlHttpRequest object is a
browser-side API to access a remote server and is available in almost
all of modern browsers. The XmlHttpRequest object enables a client to
fetch new data from a remote server using http GET or POST requests
without the need to navigate across pages. The server access
can be programmed as synchronous or asynchronous, the latter using a JavaScript
callback mechanism.
- Style Sheets (CSS) - CSS is used to define the look
and feel and the positioning and sizing of components on a server. Using
external CSS resources, you can keep the visual appearance of an application independent from the representation of the view, which in the
Ajax case mostly is built using JavaScript.
- HttpServlet - The HttpServlet is used to simulate
the server session to demonstrated behind the scene data fetching with
Ajax.
Build an Ajax application with Oracle JDeveloper 10.1.3
Following the details listed in this section you build "Hello Ajax"
incrementally starting with a static HTML client reading a text string
from a server-side file. By the end of this how-to, you will have developed a Web
page that reads its data from a servlet on the server, using a CSS style
sheet to establish alternating background colors for the retrieved data
rows. An input text field allows you to provide your input to the printed
message. Download a complete Oracle JDeveloper 10.1.3 workspace
here.
Build a Synchronous Ajax page
| 1. |
Open Oracle JDeveloper 10.1.3 and create a new application,
by choosing File > New > New Application
from the JDeveloper menu and New Gallery. In the create dialog,
type in the JDeveloper application name as "HelloAjax"
and provide other information as needed. You don't need to select
an application template because a default JDeveloper project is
sufficient.
|
| 2. |
Give the default JDeveloper project a name like "Ajaxprj".
|
| 3. |
Open the JDeveloper New Gallery by choosing New
from the context menu on the Ajaxprj node. |
| 4. |
Create a new HTML page helloAjax.hml. Verify
the helloAjax.html file is created in the public_html directory
so it can be run by the embedded OC4J web container.
|
| 5. |
Create a text file helloAjax.txt. To create the
text file, choose the General > Simple Files entry
in the JDeveloper New Gallery. |
6. |
Create a JavaScript file helloAjax.js.The JavaScript
file can be created as an option of the Web Tier > HTML
entry. Again, make sure both file are created in the public_html directory
of the JDeveloper "Ajaxprj" project |
7. |
Open the helloAjax.html file in the source code
view, set the cursor between the <head></head> elements
and select Html Common > Script from the JDeveloper
Component Palette (ctrl+shift+P). In the opened dialog, select the
helloAjax.js file entry.This creates a reference
to the JavaScript in the html file to ensure the JavaScript code
is available when the HTML page is loaded to the client.
|
8. |
Open the helloAjax.js file in the source editor
and copy the following JavaScript code into it.
var xmlHttpRequestHandler = new Object();
xmlHttpRequestHandler.createXmlHttpRequest = function(){
var XmlHttpRequestObject;
if (typeof XMLHttpRequest != "undefined"){
XmlHttpRequestObject = new XMLHttpRequest();
}
else if (window.ActiveXObject){
// look up the highest possible MSXML version
var tryPossibleVersions=["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0",
"MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp", "Microsoft.XMLHttp"];
for (i=0; i< tryPossibleVersions.length; i++){
try{
XmlHttpRequestObject = new ActiveXObject(tryPossibleVersions[i]);
break;
}
catch (xmlHttpRequestObjectError){
//ignore
}
}
}
return XmlHttpRequestObject;
}
The JavaScript is a reusable code that initializes the XmlHttprequest
object and returns a handle to the caller. The XmlHttpRequestObject
variable is created as a handler to the createXmlHttpRequest
function. JavaScript allows object oriented programming to some
degree and using a variable as a reference to a function avoids
naming conflicts in case that a JavaScript file contains multiple
functions with similar names.
The XmlHttpRequestObject variable
of the createXmlHttpRequest function
is created to hold the XmlHttpRequest object reference. Following
the code, you will notice that we look for the XmlHttpRequest object
and the XmlHttp object. Though InternetExplorer and the rest of
the browser world support XmlHttprequest objects, its named differently
in InternetExplorer. If the first condition typeof
XMLHttpRequest != "undefined" succeeds
then the client browser is Mozilla, Safaris or any non IE browser
that supports asynchronous JavaScript request and response.
If the condition window.ActiveXObject
is true then the client browser is IE. The Microsoft browser also
distinguishes its version of XmlHttp support and as a developer
you should prefer using the latest available support. The for()
loop tests the browser support for a specific XmlHttp version from
newer versions to older versions and references the most recent
version support in the XmlHttpRequest object reference.
Using the XmlHttpRequest object reference, you can issue
server calls from a HTML page using JavaScript. Dependent on whether
a request is issued synchronously or asynchronously, the browser
waits for the server to respond or uses a JavaScript callback handler
to notify the page about the server response. Following this hands-on,
you will work with both options.
|
9. |
Save your work.
|
10. |
Open the helloAjax.txt file in JDeveloper and type hello
Ajax as a text message and save
the file. |
| 11. |
You are done with the pre-requisite work and can now focus on building
the HTML page, which is the actual Ajax client. Open the helloAjax.html
file in the source view editor. |
| 12. |
Place the cursor between the <head>...</head> elements
and select the Html Common > Script entry in
the Component Palette. This time you don't reference an external
JavaScript file but type the JavaScript code content directly into
the Content text area of the dialog. The following
JavaScript code turns the static HTML file into a dynamic Ajax client,
referencing the xmlHttpRequestHandler
created in the helloAjax.js script.
function doTheAjaxThing(){
var PAGE_SUCCESS = 200;
var requestObject = xmlHttpRequestHandler.createXmlHttpRequest();
requestObject.open("Get","helloAjax.txt",false);
requestObject.send(null);
if (requestObject.status==PAGE_SUCCESS){
var div_handle = document.getElementById("message");
//check if DIV element is found
if(div_handle){
div_handle.innerHTML+=''+'br>'+requestObject.responseText;
}
}
else{
alert ("Request failed");
}
}
The function doTheAjaxThing is called
from an input button on the HTML page and obtains the "hello
Ajax" strings from the server side text file. After pressing
OK on the Script dialog, the function is added
to the HTML page header, wrapped in a pair of <script>...</script>
elements. The difference between JavaScript code that is referenced
from a file and JavaScript directly added on a page is that the
former can be reused within many other HTML pages, which is why
it should contain generic code only.
The script creates a variable requestObject
that obtains a handle to the XmlHttpRequest object using the xmlHttpRequestHandler
reference in the helloAjax.js file. Note that the page don't need
to bother whether it runs in IE or Mozilla. Sorting out the browser
type is deferred to the reusable JavaScript file. On the requestObject
handle you call open() passing three arguments. The first arguments
specifies the access, which can be any allowed server access like
GET, POST or HEAD. The second argument references the URI source
to read from. In this example the resource is a text file, later
it will be a HttpServlet. Note that JavaScript security, also referred
to as the JavaScript sandbox, doesn't allow you to access any other
server than the one the code is downloaded from. The third argument
is a Boolean type that defines whether the call should be synchronous
(false) or asynchronous (true). Using synchronous requests will
makes the browser wait for the serve to respond, which is not what
you want to see happening in a production application when fetching
lot of data from the server. You will use asynchronous server access
later in this hands-on.
The requestObject.send(null)> method
call on the XmlHttp Request object sends the request to the server.
If this was a POST request, then the null argument
value could be replaced with a list of request parameters that for
the server to work with.
Because this example uses a synchronous server call, the browser
waits for the server response before proceeding. The http code send
by the server on success of the request is 200. The success condition
is checked with requestObject.status==PAGE_SUCCESS
before the server response is read from the requestObject using
a call to requestObject.responseText,
which is method exposed on the XmlHttpRequest object. The rest of
the code references a DIV HTML element on the page
that is accessible through the DOM tree and that is used to display
the server response.
Note: The requestObject.responseText
is used to access plain text response from the server. To obtain
XML formatted data, use the XMLHttpRequest object's responseXML
method instead. For an example of how to use responseXML, see "A
Hype-Free Introduction to Ajax". Applications that need
to dynamically determine the response types can do this as follows:
var contentType = requestObject.getResponseHeader("content-type");
The possible returned content types are 'text/xml' or 'text/plain',
indicating XML or plain text content.
|
| 13. |
The remaining work left is to create a input button on the HTML
page that calls the >doTheAjaxThing
function and a <DIV> element that displays
the result. In the code editor view of the helloAjax.html file,
copy the following HTML source between the <body>...</body>
elements.
<input type="button" value="Press Me" onclick="doTheAjaxThing();"/> <div id="message"> </div>
The onclick event that is added to
the input button calls the doTheAjaxThing
method on mouse click. The <DIV> element has an id
attribute that is used to give the element a unique name so it can
be accessed directly in the DOM tree.
|
14. |
To avoid the browser caching the static HTML page, which can
be annoying when testing Ajax pages, add the following line between
the <head> and </head> element
<meta http-equiv="pragma" content="no-cache"></meta>
Note that you can have many <meta ...> elements set between
the <head> elements. This one tells the browser not to cache
this page and its content.
|
| 15. |
The HTML file now should look like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"></meta>
<title>Hello Ajax from file</title>
<script src="helloAjax.js" type="text/javascript"></script>
<script type="text/javascript">
function doTheAjaxThing(){
var PAGE_SUCCESS = 200;
var requestObject = xmlHttpRequestHandler.createXmlHttpRequest();
requestObject.open("Get","helloAjax.txt",false);
requestObject.send(null);
if(requestObject.status==PAGE_SUCCESS){
var div_handle = document.getElementById("message");
//check if DIV element is found
if(div_handle){
div_handle.innerHTML+='<br></'+'br>'+requestObject.responseText;
}
}
else{
alert ("Request failed");
}
}
</script>
</head>
<body>
<input type="button" value="Press Me" onclick="doTheAjaxThing();"/>
<DIV id="message"></DIV>
</body>
</html> |
| 16. |
Save your work and run the HTML file.
|
| 17. |
Press the button multiple times. The result should be as shown
below.
Note that the page appends all strings read from the server. To
prove that this ia Ajax, hit the page reload button and see all
the string getting deleted from the page. |
Congratulation, you created your first Ajax program!
Enhancing Your Ajax application
The following exercise is builds on the previous example and replaces
the helloAjax.txt file with a Http Servlet. Because a servlet is more
dynamic than a file in that it can contain logic to modify the format
of the response based on pre-defined definitions, you use a CSS style
sheet to color the returned rows alternating and also display a text typed
in by the page user.
| 1. |
Open the JDeveloper New Gallery using
the New option on the Ajaxprj project.
Choose the CSS File choice of the Web Tier
> HTML tree entry. Give the file a name of helloAjax.css,
and again make sure it gets added under the public_html
directory. |
2. |
Delete the stylesheet code that JDeveloper generates by default
|
| 3. |
Copy or type the following code into the stylesheet file and save
it.div.message b.red
{
background-color: gray;
color: RED;
font-family: Arial, Helvetica, sans-serif;
} div.message b.green
{
background-color: yellow;
color: GREEN;
font-family: Arial, Helvetica, sans-serif;
}
The div.message b.red tag writes
all <b> elements with a gray background color and a red font
color that have a class attribute of "red" and that are
embedded as a child element in a HTML <DIV> element with a
class attribute of message. The <DIV> and <b> HTML elements
are created dynamically as part of the server response returned
to the asynchronous Ajax request.
|
4. |
To create the Http Servlet, select New from
the JDeveloper context menu and select the Web Tier >
Servlets entry. From the available items, choose HTTP
Servlet. Name the servlet class HelloAjax
and keep the default values for all other fields and dialogs. This
will create a Http Servlet that is mapped to the /helloajax
name in the web.xml deployment descriptor. |
| 5. |
Add two instance fields
private int counter = 0;
private String name="";
to the servlet, directly under the private static final
String CONTENT_TYPE = "text/html; charset=windows-1252";
field.
|
| 6. |
Change the code of the servlet doGet method to
look as follows
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
++counter;
name = request.getParameter("name") != null?(String)request.getParameter("name"):null;
//init cap
name="From "+name;
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
if(counter % 2 == 0)
{
out.println("<b class='green'>Hello Ajax "+name+" </b><br/>");
}
else
{
out.println("<b class='red'>Hello Ajax "+name+" </b><br/>");
}
out.close();
}
The servlet expects a request parameter "name" that contains
the user input to append to the Hello Ajax message. Every even row
is printed with a CSS class reference 'green' and every uneven row
with a CSS class reference of 'red'. Because the XmlHttpRequest
output is printed within a pair of <DIV></DIV> elements,
the stylesheet to color the output addresses the <b> element
as div b.green or div b.red. As
you will later add the class="message" attribute to the
HTML DIV element, the resulting CSS reference is div.message
b.red and div.message b.green, which are
the CSS names you defined earlier in the helloAjax.css file.
|
7. |
Save your work.
.
|
8. |
Open the helloAjax.html file in the JDeveloper
code view editor. |
| 9. |
Change the content of the HTML <body> from
<body>
<input type="button" value="Press Me" onclick="doTheAjaxThing();"/>
<div id="message"></div>
</body>
to
<body>
<form name="form1" action=""> <input type="button" value="Press Me" onclick="doTheAjaxThing();"/> <input type="text"id="name" name="name"/> </form> <div id="message" class="message"></div> </body>
The HTML file now contains an additional text field for the user
to type in a string for output. The name input field has an id
attribute of "name", which makes it accessible from JavaScript
using the browser DOM tree. The exact location of the text field
is document.form1.name.
The last changes is the class attribute, which
is added to the <div> element to be
addressed by the style sheet file. |
| 10. |
Switch to the design view of the helloAjax.html file. Select the
helloAjax.css entry in the Application Navigator
and drag and drop it onto the HTML page. This creates a reference
from the HTML page to the stylesheet at runtime. |
11. |
Again, open the helloAjax.html file in the source code view and
look for the doTheAjaxThing() method between the
<head></head> element pair. |
| 12. |
Add the first line highlighted in bold to the JavaScript function
and replace the existing requestObject.open() method
call with the second highlighted code line.
function doTheAjaxThing(){
var requestObject;
var PAGE_SUCCESS = 200;
var param="name="+(document.form1.name.value.length >0 ?document.form1.name.value:"nobody");
requestObject = xmlHttpRequestHandler.createXmlHttpRequest();
requestObject.open("Get","helloajax?"+param,false);
requestObject.send(null);
...
The first line creates a variable param that reads the value of
the input text field. To make sure the value isn't left empty, JavaScript
is used to test the length of the input string and if it is left
blank, replaces it with "nobody".
The requestObject.open method call
is changed in that instead of the helloajax.txt file, it now refers
to helloajax, which is the server
side web.xml name of the Http Servlet. Because the request is a
GET request, the name request parameter is appended
to the servlet reference using a question mark '?'.
As you see, from a XmlHttpRequest point of view, the change required
to switch between calling a static file on the server and calling
a servlet instead is minor. |
13. |
Optionally, change the HTML <tile> element in the header
to
<title>Hello Ajax from servlet</title>
|
14. |
Save your work and run the helloAjax.html file.
|
You will notice a slight delay the first time you run the application.
This delay is caused by the initial startup time required by the servlet.
This delay doesn't make a good impression to the users, which is why in
the next section you are going to change the synchronous XmlHttpRequest
call to an asynchronous call.
Making Your Ajax Application Asynchronous
Asynchronous requests allow the application user to continue his work
in the browser while waiting for the server response. If the user cannot
proceed with his work unless the server responded, then still using an
asynchronous request is a better approach than synchronous call. For example,
instead of the user staring at a pressed button, you can show him some
nice "end-user entertainment" widgets, like a progress bar.
For this part of the hands-on we are not going that far and instead only
change the synchronous call to a asynchronous call.
| 1. |
Replace the existing JavaScript section that the
defines the doTheAjaxThing() function in the helloAjax.html
page with the following to make the request asynchronous:
<script type="text/javascript">
var requestObject;
var READY_STATE_COMPLETE = 4;
var PAGE_SUCCESS = 200;
function doTheAjaxThing(){
param="name="+(document.form1.name.value.length >0 ?document.form1.name.value:"nobody");
requestObject = xmlHttpRequestHandler.createXmlHttpRequest();
requestObject.onreadystatechange=onReadyStateChangeResponse;
requestObject.open("Get","helloajax?"+param,true);
requestObject.send(null);
}
function onReadyStateChangeResponse(){
var ready = requestObject.readyState;
var status = requestObject.status;
if(ready==READY_STATE_COMPLETE && status == PAGE_SUCCESS){
var div_handle = document.getElementById("message");
//check if DIV element is found
if(div_handle){
div_handle.innerHTML+=' '+'br>'+requestObject.responseText;
}
}
}
</script>
The differences between this asynchronous request handling and
the previous synchronous call are highlighted in bold. Because the
browser doesn't wait for the server to respond, this example uses
a JavaScript callback that is a function called by the XMLHttpRequest
object on state change. There are four states of interest:
0 |
The request is initialized, which is the state
before the open() method is called on the XmlHttRequestObject. |
1 |
The request is ready to be sent. |
2 |
The request was sent and is processed on the server. |
3 |
The server processes the request |
4 |
The response is complete and available for further client
side handling |
The state you are most interested in is indicated by a state value
of 4. In the JavaScript function above, for better reading, this
value is assigned to a variable JavaScript variable READY_STATE_COMPLETE.
Don't confuse state with status. The state is returned by the XmlHttpRequest,
while the status is a HTTP code that tells you about the requested
access. If for example the requestObject status is 403 then you
accessed a server resource that you are not authenticated or authorized
for. This status for sure needs a different client handling than
200, which indicates a successful server access.
To register the JavaScript callback handler onReadyStateChangeResponse
with the XmlHttprequest object, you assign it as a value to the
XmlHttpRequest onreadystate method, requestObject.onreadystatechange=onReadyStateChangeResponse,
which is one of the exposed functionality of the XmlHttpRequest
object.
The JavaScript function onReadyStateChangeResponse()
can be named as you please, as long as the same name is assigned
as a value to to requestObject.onreadystatechange.
Before you can read the returned message body you need to perform
the mentioned checks for the ready state to be 4 and the request
status to be 200. The rest of the code is the same as in the examples
before. |
2. |
Save your work and run the application.
Note that still you see a delay between pressing the button and
the server response, but this time the button is released immediately. |
Basic Troubleshooting
The most common problems you find with Javascript is the misspelling
of components and variables and the addressing of non-existing properties
on a DOM component. There exist debuggers for JavaScript that you can
get for free on the Internet. However, for "quick and dirty"
debugging, you can use alert("test"); or document.write("test");
statements to print information on the client. On the server side you
use the Oracle JDeveloper debugger for the Java code you access, or use
System.out.println("test"); there as well.
Summary
This how-to aims to give you a first hands-on experience of how to work
with Ajax in Oracle JDeveloper 10.1.3. As I mentioned in the introduction,
there is not much required to program with Ajax. If you want to do more
advanced Ajax programming, you will find yourself looking deeper into
JavaScript, CSS, and http message codes. From the perspective of the XmlHttpRequest
object, this is it: A simple object (or API) with a big impact on Web
application development. Because no specific Ajax support is needed by
an IDE, you can browse the Internet for more examples and existing javaScript
libraries that you use within your application development using Oracle
JDeveloper.
Although the technology involved in building Ajax applications has been
around for years, Ajax as a pattern is new and a lot of growth is expected
in this area. It should lead to more improved clients that eventually will become
mainstream for all kinds of Web application developers, including those
with a 4GL background.
Read More about Oracle and Ajax
Read and learn more about Oracle and Ajax! Visit our Ajax
page on the Oracle Technology Network (OTN) website.
Frank Nimphius is a product manager for Oracle Developer Tools and an Oracle ACE. You can read his blog at thepeninsulasedge.com/frank_nimphius/. |