Amazon Class AJAX Part1
Reference: https://developer.mozilla.org/en/AJAX/Getting_Started
AJAX was a designed to allow the client to send data to the server without having to have the rest the page be reloaded by the browser. Imagine if you were playing a video game and you had to have the whole screen refresh every time you clicked a mouse. That would make it unusable no matter how fast your computer was.
Circa 1998, asynchronous programming was starting to take hold inside companies who knew what they were doing. Google was building event driven C++ code( async
C++ templates is described here: http://www.scs.stanford.edu/06wics240d/sched/readings/sfs.pdf
) for GFS and MSFT introduced async programming in the server to the web browser in Internet Explorer 5.5. This allowed the browser to make a request to the server by submitting a callback function. This was not seen before in browser client side code. This worked beautifully in the world of slow network connections where the user population was dominated by AOL users trying to download content over slow POTS lines.
MSFT created AJAX by introducing a new JS object called XMLHTTPRequest object.
Another initiative circa 1998 was the prediction XML would be the lingua franca between computers and would be sending huge volumes of XML data between them as a result of Internet connectivity.
In reality, very few applications now use XML to send data between a browser and server. AJAX should really be called AJAJ (Asynchronous Javascript JSON) since most traffic between Servers and browsers is formatted in JSON or in our examples in simple text.
To implement AJAX you need 4 things:
1.
Create an XMLHTTPRequest var requestObj = new XMLHTTPRequest(); var requestObj = new ActiveXObject(“Microsoft.XMLHTTP”); combine the 2 by testing for the functionality as: var requestObj; if(window.XMLHTTPRequest){
requestObj = new XMLHTTPRequest();
}else if(window.ActiveXObject){
requestObj = new ActiveXObject(“Microsoft.XMLHTTP”);
}
2.
Add a callback function to the XMLHTTPRequest object and send the AJAX
Request. This callback function is scheduled for execution when the response from the server reaches the browser. requestObj.onreadystatechange = handleResponse;
requestObj.onreadystatechange = handleResponse;
requestObj.open('GET', weatherURL, true);
requestObj.send(null);
Set up the parameters for the request to the server, this includes the URL and any encoded parameters. A url is called a fat url when it contains question marks indicating name/value pairs are in the header. Send the request to the sender.
3.
Write the server method to accept the browser request, decode it and send back a response. choose POST. Note we used GET above:
4.
Decode the response from the Server. The data is inside XMLHttpResponse,
In our server method we will use a JavaServlet which will implement a doGet method if we specify GET in the XMLHttpRequest or a doPost method if we
Here is the full code for an WebPage implementing an AJAX call to a Yahoo Weather
Server:
<script type="text/javascript">
var requestObj;
var textBoxArray = [];
var zipcode;
function getWeather() {
zipcode = document.weather.ZipCode.value;
var weatherURL = "http://cgi.stanford.edu/~class-cs193c-1066/cgibin/a3.php?yws_path="
+ encodeURIComponent("p=" + zipcode);
if(window.XMLHttpRequest){
requestObj = new XMLHttpRequest();
} else if (window.ActiveXObject) {
requestObj = new ActiveXObject("Microsoft.XMLHTTP");
}
requestObj.onreadystatechange = handleResponse;
requestObj.open('GET', weatherURL, true);
requestObj.send(null);
}
function handleResponse() {
if (requestObj.readyState == 4) {
var parseString = requestObj.responseText;
if(parseString.match("Error")!=null){
document.weather.ZipCode.value="Invalid Zipcode";
return false;
}
var xmlDoc;
try //Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(parseString);
}
catch (e) {
try // Firefox, Mozilla, Opera, etc.
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(parseString, "text/xml");
}
catch (e) { return;
}
} var title=xmlDoc.getElementsByTagName("title"); var city = xmlDoc.getElementsByTagName("yweather:location")[0].getAttribute("city"
); var tempUnits = xmlDoc.getElementsByTagName("yweather:units")[0].getAttribute("tempe rature"); var currentTemp = xmlDoc.getElementsByTagName("yweather:condition")[0].getAttribute("te mp"); var currentCond = xmlDoc.getElementsByTagName("yweather:condition")[0].getAttribute("te xt");
textBoxArray[textBoxArray.length] = city + " " + currentTemp + tempUnits
+ " " + currentCond + " \n";
}
}
The code above is available under AWSServlet/AJAXPart1.html. You should see alerts in every stage of the AJAX response cycle.
Let’s first look at how to implement AJAX inside an Eclipse Dynamic WebProject where we will have the server AND the html page in the same project.
Demo Lab #1 AJAX Servlet
We are going to implement an AJAX server and webpage. These next 2 demos are under AWSServlet/AJAXPart2.html and AWSServlet/AJAXPart3.html
You should see alerts in each stage of the AJAX cycle.
AJAX is composed of several components, the client and server. Both have to be working together.
We are going to start integrating jQuery into our code practice. jQuery replaces the
AJAX code in the following sections:
1. to replace the body onload() function with $(document).ready(). For complicated webpages, $(document).ready() can be true before the body is ready(true before image downloads). Body.onload() implies all downloads including images have completed. $(document).ready() implies the DOM is ready which in some cases happens before body.onload() fires.
OK to simplify the code using the JQuery $.ajax object. The AJAX object simplifies our code by allowing us to enter Ajax Parameters in a function/JSON object syntax.
First get an alert in the callback function working without decoding any data from the server.
Then add the function to print data received from the server:
Debugging reminder make sure you add the commas at the end of line
Do not skip steps, JS is hard to debug because all of these errors are in runtime. Get the alert working first without the callback function
Add the callback function in a different format, without using
Anonymous functions. Add the function named serverResponseForGet.
x is the global return value which encapsulates the response from the ajax function.
Use Firebug or the Google Chrome debugger.
The code above has the server decode data sent from the browser simulating a form submission for the variable or parameter named name, with value John. The server prints out the result in the catalina.out log file or in the eclipse console window. jqXHR is a jQuery object returned by $.ajax() which replaces XMLHttpRequest and is assigned to the variable x in the example above. jQuery replaces the traditional browser AJAX respons variables such as readyonstatechange and responseText with jqXHR.
Here is an example decoding JSON from the server:
JSONServlet:
/**
* @see HttpServlet#doPost(HttpServletRequest request,
HttpServletResponse
* response)
*/
@Override protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws
ServletException, IOException {
System.
try { out .println( "JSON SERVLET POST" );
JSONObject json = new JSONObject().put( "fish" ,
"nemo" ); response.getWriter().write(json.toString());
} catch (Exception e) { e.printStackTrace();
}
}
JS Code:
< script type = "text/javascript" >
$(document).ready( function (){
$( "form" ).submit( function (){ event.preventDefault(); var xhqr = $.ajax({
url: "http://localhost:8080/AWSServlet/JSONServlet" ,
dataType: 'json' ,
type: 'POST'
}).success( function (data, statusCode,jqxhr){ alert( "statuscode:" +statusCode); var serverJSON = $.parseJSON(jqxhr.responseText); alert( "server response:" +serverJSON.fish)})
.error( function (){alert( "error" );
});
});
});
</ script >
Sending Form data via POST to the Server
AJAXExample3 is an example of overriding the FORM submit mechanism using jQuery. This is a very common design pattern seen in autocomplete and login boxes.
You may want to use this in creating your own version of the AWS Management
Console.
$(document).ready( function (){
$( "form" ).submit( function (event){
//prevent the browser from sending an AJAX request to the server,
//we will override this event.preventDefault();
//note we are setting up the action and method attribute equivalent
//we left them out of the html. var url= "http://localhost:8080/AWSServlet/JacksonServlet" ;
$form=$( this );
term =$form.find( 'input[name="textbox"]' ).val();
//send request to server
$.post( url, { textbox: term }, function ( data ) {
$( "#result" ).append( "<p>Server response below:</p>" ,data);
}
);
});
});
There are 3 rd party jQuery extensions which are not necessary which use mutually exclusive functions $.ajaxForm and $.ajaxSubmit to override the submit function in an AJAX form.
Javascript Configuration: either download the jquery packages (jquery and jquery
UI) to your project (don’t forget to make Eclipse copy these to the deployment descriptor) or use the Google CDNS. I like to download them to my computer so I can work without network access.
Servlet Configuration:
Use log4j. this keeps the logger out of the ServerConfig which saves on resources.
Most do not use the built in Java Logger.
Add the log4j.properties to webcontent. Make sure to add this to the deployment descriptor
Eclipse Configuration: make sure to include the third party libraries under the
Eclipse project and make sure they are in the deployment assembly so they are copied over where the Tomcat server can find them.