Lean AJAX
Lean AJAX
Lean AJAX
For live Ajax & GWT training, see training courses at http://courses.coreservlets.com/.
Taught by the author of Core Servlets and JSP, More Servlets and JSP, and this tutorial. Available at public venues, or customized versions can be held on-site at your organization.
Courses developed and taught by Marty Hall
Java 5, Java 6, intermediate/beginning servlets/JSP, advanced servlets/JSP, Struts, JSF, Ajax, GWT, custom mix of topics
Servlets,Spring, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Java 5, Java 6, etc. Ruby/Rails coming soon. JSP, Hibernate, EJB3, Ruby/Rails Developed and taught by well-known author and developer. At public venues or onsite at your location. Contact hall@coreservlets com for details
Motivation
Customized J2EE Training: http://courses.coreservlets.com/
Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Java 5, Java 6, etc. Ruby/Rails coming soon. Developed and taught by well-known author and developer. At public venues or onsite at your location.
Why Ajax?
HTML and HTTP are weak
Non-interactive Coarse-grained updates
Handle response
Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
HTML
Loads JavaScript Designates control that initiates request J2EE training: http://courses.coreservlets.com Gives ids to input elements that will be read by script
10
Initiate Request
function sendRequest() { Response handler function name request = getRequestObject(); request.onreadystatechange = handleResponse; request.open("GET", "message-data.html", true); request.send(null); }
URL of server-side resource Don't wait for response (Send request asynchronously)
12
Handle Response
function handleResponse() { if (request.readyState == 4) { alert(request.responseText); } Response is returned from server }
(handler gets invoked multiple times)
13
14
http://www.mozilla.org/projects/venkman/ https://addons.mozilla.org/firefox/216/
J2EE training: http://courses.coreservlets.com
HTML Code
Use xhtml, not HTML 4
In order to manipulate it with DOM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">...</html> Due to IE bug, do not use XML header before the DOCTYPE
XHTML specification recommends using it But... Internet Explorer will switch to quirks-mode (from standards-mode) if DOCTYPE is not first line.
Many recent style sheet formats will be ignored So omit XML header
Scripts will not load if you use <script .../> instead of <script...></script> J2EE training: http://courses.coreservlets.com
18
<html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Ajax: Simple Message</title> <script src="show-message.js" type="text/javascript"></script> </head> <body> <center> <table border="1" bgcolor="gray"> <tr><th><big>Ajax: Simple Message</big></th></tr> </table> <p/> <form action="#"> <input type="button" value="Show Message" onclick="sendRequest()"/> </form> </center></body></html> J2EE training: http://courses.coreservlets.com
19
Note: executing this example Since main page uses relative URL and HTML content has no dynamic content, you can run this example directly from the disk without using a server. But later examples require dynamic content, so all examples will be shown running on Tomcat. J2EE training: http://courses.coreservlets.com
20
Steps
JavaScript
Define an object for sending HTTP requests Initiate request
Get request object Designate a response handler function
Supply as onreadystatechange attribute of request
Handle response
Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
HTML
Loads JavaScript from centralized directory Designates control that initiates request J2EE training: http://courses.coreservlets.com Gives ids to input elements that will be read by script
23
24
Initiate Request
function sendRequest(address) { request = getRequestObject(); request.onreadystatechange = showResponseAlert; request.open("GET", address, true); request.send(null); }
Relative URL of server-side resource. (In this example, we will pass in the address of a JSP page.)
25
Handle Response
function showResponseAlert() { if ((request.readyState == 4) && (request.status == 200)) { alert(request.responseText); } }
Server response came back with no errors. (HTTP status code 200.)
26
27
HTML Code
Loads JavaScript from central location
<script src="../scripts/ajax-basics.js" type="text/javascript"></script>
28
29
Otherwise JSP cannot execute Otherwise status code is -1, not 200
31
Steps
JavaScript
Define an object for sending HTTP requests Initiate request
Get request object Designate a response handler function
Supply as onreadystatechange attribute of request
Handle response
Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
HTML
Loads JavaScript from centralized directory Designates control that initiates request J2EE training: http://courses.coreservlets.com Gives ids to input elements that will be read by script
34
35
Initiate Request
function sendRequest(address) { request = getRequestObject(); request.onreadystatechange = showResponseAlert; request.open("GET", address, true); request.send(null); }
No changes from previous example
36
Handle Response
function showResponseAlert() { if ((request.readyState == 4) && (request.status == 200)) { alert(request.responseText); } }
No changes from previous example
37
Servlet Code
package coreservlets; import ... public class ShowTime extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); Date currentTime = new Date(); String message = String.format("It is now %tr on %tD.", currentTime, currentTime); out.print(message); } } J2EE training: http://courses.coreservlets.com
39
web.xml
... <servlet> <servlet-name>ShowTime</servlet-name> <servlet-class>coreservlets.ShowTime</servlet-class> </servlet> <servlet-mapping> <servlet-name>ShowTime</servlet-name> <url-pattern>/show-time</url-pattern> </servlet-mapping> ...
40
41
43
Steps
JavaScript
Define an object for sending HTTP requests Initiate request Get request object Designate a response handler function
Supply as onreadystatechange attribute of request
Send data Handle response Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
HTML
Loads JavaScript from centralized directory Designates control that initiates request Gives ids to input elements that will be read by script
44
JavaScript Code
No changes from previous example
45
Servlet Code
public class ShowTimeInCity extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); String city = request.getParameter("city"); ... String message = TimeZone.getTimeString(city); ... out.print(message); } ...
47
TimeZone Class
Maintains a list of cities and associated time zones
Given the name of a city, it finds the difference in hours between that city's time and server time (east coast US)
48
49
With Ajax, end users don't see URL, so choice is relatively arbitrary
51
Steps
JavaScript
Define an object for sending HTTP requests Initiate request Get request object Designate a response handler function
Supply as onreadystatechange attribute of request
Send data Handle response Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
HTML
Loads JavaScript from centralized directory Designates control that initiates request Gives ids to input elements that will be read by script
52
Read data
var value1 = document.getElementById("some-id").value;
54
Initiate Request
function sendRequestWithData(address, data, responseHandler) { request = getRequestObject(); request.onreadystatechange = responseHandler; request.open("POST", address, true); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(data); } function showTimeInCity() { var address = "../show-time-in-city"; var city = document.getElementById("city").value; var data = "city=" + escape(city); sendRequestWithData(address, data, showResponseAlert); } No changes from previous example
55
Handle Response
function showResponseAlert() { if ((request.readyState == 4) && (request.status == 200)) { alert(request.responseText); } }
No changes from previous example
56
HTML Code
<!DOCTYPE html PUBLIC "..." "http://www.w3.org/..."> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Ajax: Time</title> <link rel="stylesheet" href="../css/styles.css" type="text/css"/> <script src="../scripts/ajax-basics.js" type="text/javascript"></script> </head> <body> ... <form action="#"> City: <input type="text" id="city"/><br/> <input type="button" value="Show Time in City" onclick="showTimeInCity()"/> </form> </center></body></html>
57
Servlet Code
public class ShowTimeInCity extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); String city = request.getParameter("city"); ... String message = TimeZone.getTimeString(city); ... out.print(message); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
58
59
61
Steps
JavaScript
Define an object for sending HTTP requests Initiate request Get request object Designate a response handler function Initiate a POST request to a servlet Send data Handle response Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
Use innerHTML to insert result into "div" element
HTML
Loads JavaScript from centralized directory Designates control that initiates request Gives ids to input elements that will be read by script Defines a blank "div" element with a known id
62
JavaScript
Finds element (getElementById) and inserts text into innerHTML property
document.getElementById("resultText").innerHTML = request.responseText;
63
64
Initiate Request
function sendRequestWithData(address, data, responseHandler) { request = getRequestObject(); request.onreadystatechange = responseHandler; request.open("POST", address, true); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); No changes from previous example request.send(data); }
function displayTimeInCity() { var address = "../show-time-in-city"; var city = document.getElementById("city").value; var data = "city=" + escape(city) + "&useHTML=true"; sendRequestWithData(address, data, showResponseText); }
65
Handle Response
function showResponseText() { if ((request.readyState == 4) && (request.status == 200)) { document.getElementById("resultText").innerHTML = request.responseText; } }
66
Servlet Code
public class ShowTimeInCity extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); String city = request.getParameter("city"); boolean useHTML = false; if (request.getParameter("useHTML") != null) { useHTML = true; } String message = TimeZone.getTimeString(city); if (useHTML) { message = String.format("<h2>%s</h2>", message); } out.print(message); } public void doPost(...) ... { doGet(request, response); } J2EE training: http://courses.coreservlets.com
68
69
Solution
Have servlet return XML content JavaScript parses XML and decides what to do with it
Secondary problem
Generating XML from a servlet is inconvenient
Secondary solution
Use MVC architecture on server
Servlet creates dynamic data JSP formats the data See detailed lecture on using MVC in Java: http://courses.coreservlets.com/Course-Materials/csajsp2.html
71
Steps
JavaScript
Define an object for sending HTTP requests Initiate request Get request object Designate a response handler function Initiate a POST request to a servlet (that uses MVC) Send data Handle response Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
Parse data. Use innerHTML to insert result into "div" element
HTML
Loads JavaScript from centralized directory Designates control that initiates request Gives ids to input elements that will be read by script Defines a blank "div" element with a known id
72
74
Initiate Request
function sendRequest() { request = getRequestObject(); request.onreadystatechange = showCityTable; request.open("POST", "../show-times-in-cities", true); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); var timezone = document.getElementById("timezone").value; request.send("timezone=" + timezone); }
75
Handle Response
function showCityTable() { if ((request.readyState == 4) && (request.status == 200)) { var xmlDocument = request.responseXML; var names = xmlDocument.getElementsByTagName("name"); var times = xmlDocument.getElementsByTagName("time"); var days = xmlDocument.getElementsByTagName("day"); var tableData = getTableStart(); for(var i=0; i<names.length; i++) { var name = names[i].childNodes[0].nodeValue; var time = times[i].childNodes[0].nodeValue; var day = days[i].childNodes[0].nodeValue; tableData = tableData + getRowData(name, time, day); } tableData = tableData + getTableEnd(); document.getElementById("resultText").innerHTML = tableData; } J2EE training: http://courses.coreservlets.com }
76
Auxiliary Functions
function getTableStart() { return("<table border='1'>\n" + " <tr><th>City</th><th>Time</th><th>Day</th></tr>\n"); } function getRowData(name, time, day) { return(" <tr><td>" + name + "</td><td>" + time + "</td><td>" + day + "</td></tr>\n"); } function getTableEnd() { return("</table>\n"); }
77
Servlet Code
response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); response.setContentType("text/xml"); String timezone = request.getParameter("timezone"); List legalZones = Arrays.asList("eastern", "central", "mountain", "pacific"); if ((timezone == null) || (!legalZones.contains(timezone))) { timezone = "eastern"; } timezone = timezone.toLowerCase(); String outputPage = String.format("/WEB-INF/results/%s.jsp", timezone); FormattedTimeAndDay timeAndDay = new FormattedTimeAndDay(timezone); request.setAttribute("timeAndDay", timeAndDay); RequestDispatcher dispatcher = request.getRequestDispatcher(outputPage); dispatcher.include(request, response);
78
79
80
Ajax Tools
Customized J2EE Training: http://courses.coreservlets.com/
Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Java 5, Java 6, etc. Ruby/Rails coming soon. Developed and taught by well-known author and developer. At public venues or onsite at your location.
script.aculo.us
http://script.aculo.us/
ExtJS
http://extjs.com/
JSON/JSON-RPC
For sending data to/from JavaScript with less parsing http://www.json.org/ http://json-rpc.org/
83
Tomahawk
http://myfaces.apache.org/tomahawk/
Ajax4JSF
http://labs.jboss.com/jbossajax4jsf/
IceFaces
http://www.icefaces.org/
http://courses.coreservlets.com/Course-Materials/jsf.html
Books
Foundations of Ajax
Asleson and Schutta. APress. Geared around Java on the server-side.
Ajax in Action
Crane, Pascarello, and James. Manning. Geared around Java on the server-side.
Professional Ajax
Zakas, et al. Wrox. Wait for 2nd edition. Geared around Java on the server-side.
85
Summary
JavaScript
Define request object
Check for both Microsoft and non-MS objects. Identical in all apps.
Initiate request
Get request object Designate a response handler function Initiate a GET or POST request Send data (null for GET)
Handle response
Wait for readyState of 4 and HTTP status of 200 Extract return text with responseText or responseXML Do something with result
Use innerHTML to insert result into "div" element
HTML
Give ids to input elements and to div. Initiate process.
Java
86
Questions?
Customized J2EE Training: http://courses.coreservlets.com/
Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Java 5, Java 6, etc. Ruby/Rails coming soon. Developed and taught by well-known author and developer. At public venues or onsite at your location.