Ajax data-handling

158 views
80 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
158
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Ajax data-handling

  1. 1. © 2010 Marty Hall Ajax: Handling Different Server Data Formats Basics: XML, JSON, and String Originals of Slides and Source Code for Examples: http://courses.coreservlets.com/Course-Materials/ajax.html Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. http://courses.coreservlets.com/Course Materials/ajax.html © 2010 Marty Hall For live Ajax & GWT training, see training t htt // l t /courses at http://courses.coreservlets.com/. Taught by the author of Core Servlets and JSP, More Servlets and JSP and this tutorial Available atMore Servlets and JSP, and this tutorial. Available at public venues, or customized versions can be held on-site at your organization. C d l d d t ht b M t H ll Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. • Courses developed and taught by Marty Hall – Java 6, servlets/JSP (intermediate and advanced), Struts, JSF 1.x, JSF 2.0, Ajax, GWT 2.0 (with GXT), custom mix of topics – Ajax courses can concentrate on 1 library (jQuery, Prototype/Scriptaculous, Ext-JS, Dojo, Google Closure) or survey several • Courses developed and taught by coreservlets.com experts (edited by Marty) – Spring, Hibernate/JPA, EJB3, Web Services, Ruby/Rails Contact hall@coreservlets.com for details
  2. 2. Topics in This Section • Building HTML tables in JavaScript • XML data – Parsing results B ildi XML d i h MVC– Building XML data on server with MVC • JSON data Parsing results– Parsing results – Building JSON data on server with MVC • String dataString data – Parsing results – Building String data on server with MVC • Combination data – Deciding what data format to use at run time5 © 2010 Marty Hall Data-Centric Ajax Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
  3. 3. Three Styles of Ajax • Content-Centric Ajax Th d th t HTML t b di l d– The server sends the exact HTML to be displayed – The client simply inserts the content into the page • But can use style sheets to somewhat customize the look Thi th h d i th i ti– This was the approach used in the previous sections • Data-Centric Ajax – The server sends raw data to the client – The client parses the data and builds the HTML – This is the approach used in this section • Script-Centric AjaxScript Centric Ajax – The server sends JavaScript functions to the client – The client executes the functions This approach is not discussed in this tutorial– This approach is not discussed in this tutorial • Inflexible: Requires the server to know too much about client 7 Data-Centric Ajax: Motivation • In many cases, the server data is intimately i d ifi HTM f h litied to a specific HTML form on the client – In that case, it makes good sense for the server to send HTML tags and for the client to merely insert themHTML tags and for the client to merely insert them • This is what we did previously (content-centric Ajax) • In other cases, the same server data may be used in several forms or in different pages – And the data may be used in different ways by different applicationsapplications – In that case, it makes sense for the server to send some standard data format • The client must parse (extract info from) this data format • The client must build HTML based upon the data 8
  4. 4. Review: Steps for Content-Centric AjaxSteps for Content-Centric Ajax • JavaScript – Define an object for sending HTTP requestsDefine an object for sending HTTP requests – Initiate request • Get request object • Designate an anonymous response handler function I iti t POST GET t t l t• Initiate a POST or GET request to a servlet – Put POST data in the send method – Data based on document.getElementById(id).value of some textfield – Handle responsep • Wait for readyState of 4 and HTTP status of 200 • Extract text with responseText • Use innerHTML to insert that exact text into designated element • HTML• HTML – Load JavaScript from centralized directory – Designate control that initiates request – Give ids to input elementsp – Define a blank placeholder element with a known id 9 Content-Centric Ajax: Typical ApproachTypical Approach function ajaxResultPost(address, data, resultRegion) { var request = getRequestObject();q g q j (); request.onreadystatechange = function() { showResponseText(request, resultRegion); }; request open("POST" address true);request.open("POST", address, true); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(data); } function showResponseText(request, resultRegion) { if ((request readyState == 4) &&if ((request.readyState == 4) && (request.status == 200)) { htmlInsert(resultRegion, request.responseText); } } 10
  5. 5. Steps for Data-Centric Ajax • JavaScript – Define an object for sending HTTP requestsDefine an object for sending HTTP requests – Initiate request • Get request object • Designate an anonymous response handler function I iti t POST GET t t l t• Initiate a POST or GET request to a servlet – Put POST data in the send method – Data based on document.getElementById(id).value of some textfield – Handle responsep • Wait for readyState of 4 and HTTP status of 200 • Extract data with responseText or responseXML – Build new text based on this data • Use innerHTML to insert that new text into designated elementUse innerHTML to insert that new text into designated element • HTML – Load JavaScript from centralized directory – Designate control that initiates request – Give ids to input elements – Define a blank placeholder element with a known id 11 Data-Centric Ajax: Typical ApproachTypical Approach function ajaxResultPost(address, data, resultRegion) { var request = getRequestObject();q g q j (); request.onreadystatechange = function() { showResponseText(request, resultRegion); }; request open("POST" address true);request.open("POST", address, true); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.send(data); } function showResponseText(request, resultRegion) { if ((request readyState == 4) &&if ((request.readyState == 4) && (request.status == 200)) { var text = someStringBasedOn(request.responseText); // or request.responseXML htmlInsert(resultRegion, text); } } 12
  6. 6. © 2010 Marty Hall Building HTML TablesBuilding HTML Tables in JavaScriptp Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. Utility: Building HTML Tables function getTable(headings, rows) { var table = "<table border='1' class='ajaxTable'>n" +var table <table border 1 class ajaxTable >n + getTableHeadings(headings) + getTableBody(rows) + "</table>"; return(table); } • Note – The first argument contains the headingsg g • To be inserted into th elements – The second argument is an array-of-arrays, where each sub array is a table rowsub-array is a table row • The elements in the sub-arrays will be go in td elements 14
  7. 7. Utility: Building HTML Tables (Continued)(Continued) function getTableHeadings(headings) { var firstRow = " <tr>"; for(var i=0; i<headings.length; i++) { firstRow += "<th>" + headings[i] + "</th>"; } firstRow += "</tr>n"; return(firstRow); } function getTableBody(rows) { var body = ""; for(var i=0; i<rows.length; i++) { body += " <tr>"; var row = rows[i]; for(var j=0; j<row.length; j++) { body += "<td>" + row[j] + "</td>"; } body += "</tr>n";y } return(body); } 15 Other Utilities (From Last Section) // Insert the html data into the element // that has the specified id// that has the specified id. function htmlInsert(id, htmlData) { document.getElementById(id).innerHTML = htmlData;g y ( ) } // Return escaped value of textfield that has given id. // The builtin "escape" function url-encodes characters. function getValue(id) { t ( (d t tEl tB Id(id) l ))return(escape(document.getElementById(id).value)); } 16
  8. 8. Example Usage (JavaScript) // Build a table from purely client-side information. // To test the getTable function.// To test the getTable function. function clientTable(displayRegion) { var headings = ["Quarter", "Apples", "Oranges"]; var rows = [["Q1", randomSales(), randomSales()], ["Q2", randomSales(), randomSales()], ["Q3", randomSales(), randomSales()], ["Q4" randomSales() randomSales()]];[ Q4 , randomSales(), randomSales()]]; var table = getTable(headings, rows); htmlInsert(displayRegion, table); }} function randomSales() { var sales = 1000 + (Math.round(Math.random() * 9000)); t ("$" l )return("$" + sales); } 17 Example Usage (HTML) ... <fieldset><fieldset> <legend> Building HTML Table from Client-Side Data </legend></legend> <form action="#"> <input type="button" value="Build Sample Table" onclick='clientTable("client-table")'/>onclick clientTable( client table ) /> </form> <p/> <div id="client-table"></div>d d c e t tab e /d </fieldset> ... 18
  9. 9. Example Usage (Result) 19 © 2010 Marty Hall Handling XML Data Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
  10. 10. Basic Tasks in XML • How to treat the Ajax response as XML – var xmlDoc = response.responseXML; • How to get an array of subelements lD El B T N ( )– xmlDoc.getElementsByTagName(…) • How to get an attribute of an element someElement getAttribute( )– someElement.getAttribute(…) • How to get the body content of an element – someElement firstChild nodeValuesomeElement.firstChild.nodeValue 21 Basic Tasks • Getting the raw XML data – var xmlDocument = request.responseXML; • Finding array of XML elements lD El B T N– xmlDocument.getElementsByTagName (xmlElementName); • Finding the text between start and end tagsFinding the text between start and end tags – someElement.childNodes[0].nodeValue • Call the following at least once first: lD t d tEl t li ()xmlDocument.documentElement.normalize(); • Note – In an earlier section we gave much more detail on XMLIn an earlier section we gave much more detail on XML manipulation in JavaScript 22
  11. 11. XML Utility Functions // Given an element, returns the body content. function getBodyContent(element) { element.normalize(); return(element firstChild nodeValue);return(element.firstChild.nodeValue); } 23 XML Utility Functions // Given a doc and the name of an XML element, returns an // array of the values of all elements with that name// array of the values of all elements with that name. // E.g., for // <foo><a>one</a><q>two</q><a>three</a></foo> // getXmlValues(doc, "a") would returng ( , ) // ["one", "three"]. function getXmlValues(xmlDocument, xmlElementName) { var elementArray = xmlDocument.getElementsByTagName(xmlElementName); var valueArray = new Array(); f ( i 0 i< l tA l th i++) {for(var i=0; i<elementArray.length; i++) { valueArray[i] = getBodyContent(elementArray[i]); } return(valueArray);return(valueArray); } 24
  12. 12. XML Utility Functions // Given an element object and an array of sub-element names, // returns an array of the values of the sub-elements// returns an array of the values of the sub elements. // E.g., for <foo><a>one</a><c>two</c><b>three</b></foo>, // if the element points at foo, // getElementValues(element, ["a", "b", "c"]) would return// getElementValues(element, [ a , b , c ]) would return // ["one", "three", "two"] function getElementValues(element, subElementNames) {g ( , ) { var values = new Array(subElementNames.length); for(var i=0; i<subElementNames.length; i++) { var name = subElementNames[i]; var subElement = element.getElementsByTagName(name)[0]; values[i] = getBodyContent(subElement); } return(values); } 25 General Utility Function (Update from Previous Section)(Update from Previous Section) // Generalized version of ajaxResultPost. In this // version you pass in a response handler function// version, you pass in a response handler function // instead of just a result region. function ajaxPost(address data responseHandler) {function ajaxPost(address, data, responseHandler) { var request = getRequestObject(); request.onreadystatechange = function() { responseHandler(request); };function() { responseHandler(request); }; request.open("POST", address, true); request.setRequestHeader ("Content-Type",( Co te t ype , "application/x-www-form-urlencoded"); request.send(data); }} 26
  13. 13. General Utility Function (Same as in Previous Sections)(Same as in Previous Sections) function getRequestObject() {function getRequestObject() { if (window.XMLHttpRequest) { return(new XMLHttpRequest()); } else if (window ActiveXObject) {} else if (window.ActiveXObject) { return(new ActiveXObject("Microsoft.XMLHTTP")); } else { t ( ll)return(null); } } 27 © 2010 Marty Hall Handling XML Data:Handling XML Data: Examplep Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
  14. 14. Steps • JavaScript – Define an object for sending HTTP requestsDefine an object for sending HTTP requests – Initiate request • Get request object • Designate an anonymous response handler function I iti t POST t t l t• Initiate a POST request to a servlet – Put POST data in the send method – Data based on document.getElementById(id).value of some textfield – Handle responsep • Wait for readyState of 4 and HTTP status of 200 • Extract return text with responseText or responseXML – Get text from XML with getElementsByTagName and firstChild.nodeValue – Build HTML table or other HTML data out of the textBuild HTML table or other HTML data out of the text • Use innerHTML to insert result into designated element • HTML – Load JavaScript from centralized directory – Designate control that initiates request – Give ids to input elements – Define a blank placeholder element with a known id 29 Initiate Request function xmlCityTable(inputField, resultRegion) { var address = "show-cities";var address = show cities ; var data = "cityType=" + getValue(inputField) + "&format=xml"; ajaxPost(address dataajaxPost(address, data, function(request) { showXmlCityInfo(request, resultRegion); });}); } 30
  15. 15. Handle Response function showXmlCityInfo(request, resultRegion) { if ((request.readyState == 4) &&if ((request.readyState 4) && (request.status == 200)) { var xmlDocument = request.responseXML; var headings = getXmlValues(xmlDocument, "heading"); var cities = xmlDocument.getElementsByTagName("city"); var rows = new Array(cities.length); var subElementNames = ["name", "time", "population"]; for(var i=0; i<cities length; i++) {for(var i=0; i<cities.length; i++) { rows[i] = getElementValues(cities[i], subElementNames); } var table = getTable(headings, rows); htmlInsert(resultRegion, table); } }} 31 HTML Code ... <fieldset> <legend>Getting XML Data from Server, Building HTML Table</legend> <form action="#"> <label for="city-type-1">City Type:</label> <select id="city-type-1"> <option value="top-5-cities">Largest Five US Cities</option> <option value="second-5-cities">Second Five US Cities</option> <option value="cities-starting-with-s"> US Cities Starting with 'S'</option> <option value="superbowl-hosts"> Most Recent Superbowl Hosts</option> </select> <br/> <input type="button" value="Show Cities" onclick='xmlCityTable("city-type-1", "xml-city-table")'/> </form> <p/> <div id="xml-city-table"></div> </fieldset> ... 32
  16. 16. Server Design: MVC • Logic S h h d d h h l– Set the headers, read the request parameters, compute the results – Do this in Java (called by a servlet) • Presentation – Build an XML file – Do this in JSP • Use the JSP expression language to access the resultsUse the JSP expression language to access the results • Minor variation from usual MVC – So that you can set Content-Type in servlet, use RequestDispatcher include instead of RequestDispatcher forwardRequestDispatcher.include instead of RequestDispatcher.forward • Reminder – Details on MVC and on the JSP expression language are given in h iother sections. • From the servlet and JSP tutorials 33 Servlet Code public class ShowCities extends HttpServlet { public void doGet(HttpServletRequest request,p ( p q q , HttpServletResponse response) throws ServletException, IOException { response.setHeader("Cache-Control", "no-cache"); response setHeader("Pragma" "no cache");response.setHeader("Pragma", "no-cache"); String cityType = request.getParameter("cityType"); List<City> cities = CityUtils.findCities(cityType); request.setAttribute("cities", cities); String format = request.getParameter("format"); String outputPage; if ("xml".equals(format)) { response setContentType("text/xml");response.setContentType( text/xml ); outputPage = "/WEB-INF/results/cities-xml.jsp"; } ... RequestDispatcher dispatcher = request.getRequestDispatcher(outputPage); dispatcher.include(request, response); } 34
  17. 17. Servlet Code (Continued) public void doPost(HttpServletRequest request, HttpServletResponse response)HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }} • I will use POST from the JavaScript – But having GET support makes it easier to test interactively – So support bothSo support both 35 Supporting Code (City java)(City.java) • Constructor public City(String name, int timeZone, int pop) { setName(name); setTimeZone(timeZone); setPop(pop);setPop(pop); } • Getter methods – getName – getTime, getTimeZone • Assumes server is in US east coasts subtracts 0-3 hoursAssumes server is in US east coasts, subtracts 0 3 hours based on time zone – getPop Raw population as an int• Raw population as an int – getPopulation • Formatted population as a String with commas36
  18. 18. Supporting Code (CityUtils.java) • Map that associates city name with City private static Map<String,City> biggestAmericanCities = new HashMap<String,City>(); • Populate it with 40 largest US cities L k f ti• Lookup function public static City getCity(String name) { name = name.toUpperCase(); return(biggestAmericanCities.get(name)); } 37 Supporting Code Continued (CityUtils java)(CityUtils.java) • Map that associates category of cities with i f CiList of City private static Map<String,String[]> cityTypeMap; • Lookup function public static List<City> findCities(String cityType) { String[] cityNames = cityTypeMap get(cityType);String[] cityNames cityTypeMap.get(cityType); if (cityNames == null) { String[] twoCities = { "New York", "Los Angeles" }; cityNames = twoCities; } List<City> cities = new ArrayList<City>(); for(String cityName: cityNames) { cities add(getCity(cityName));cities.add(getCity(cityName)); } return(cities); }38
  19. 19. JSP Code (/WEB-INF/results/cities-xml jsp)(/WEB INF/results/cities xml.jsp) <?xml version="1.0" encoding="UTF-8"?> <cities> <headings> <heading>City</heading> <heading>Time</heading> <heading>Population</heading><heading>Population</heading> </headings> <city> <name>${cities[0].name}</name>{ [ ] } <time>${cities[0].time}</time> <population>${cities[0].population}</population> </city> Three more cities (omitted to make space on slide) ... <city> <name>${cities[4].name}</name> <time>${cities[4].time}</time> ( p ) <population>${cities[4].population}</population> </city> </cities> 39 XML Data: Results 40
  20. 20. Major Flaw in Design • Client-side code (good) – Can handle any number of city entries • I.e., any number of entries in array that represents the table rows • Servlet code (good) – Can handle any number of City objects • Just stores List<City> in request scope • JSP code (bad) Problems– Problems • Must know how many cities there are • Repeats description for each city – Solution • JSTL (covered in upcoming section) 41 © 2010 Marty Hall Handling JSON Data Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
  21. 21. Basic Tasks • JSON – JavaScript Object Notation. A simple textual representation of JavaScript objects that is already directly supported in JavaScript.directly supported in JavaScript. – More details will be provided in later section • Directly in JavaScripty p – var someObject = { property1: value1, property2: value2 };property2: value2, ... }; • In a string (e.g., when coming in on network) – Surround object representation in parensSurround object representation in parens – Pass to the builtin “eval” function 43 Basic Tasks: Details • Main object S d ti l i l b– Surround entire value in curly braces – Put field names in single or double quotes • Quotes can be omitted if field name is legal variable name U l b fi ld d l– Use colons between field names and values – Put commas after each fieldname: fieldvalue pair. • Field values – Strings: use single or double quotes – Numbers: no quotes needed – Arrays: use comma-separated values inside square braces– Arrays: use comma-separated values inside square braces • Putting JSON in strings – Enclose in parens and quotes U i l t th t id if h d bl• Use single quotes on the outside if you have double quotes inside – Pass result to “eval” to get an object back44
  22. 22. Basic Tasks: Example var firstObject = { field1: "string-value1",{ field1: string value1 , field2: 3, field3: ["a", "b", "c"] };} var someString = '({ f1: "val1", f2: "val2" })'; var secondObject = eval(someString); • Results – firstObject field1  "string-value1"firstObject.field1  string value1 – firstObject.field2  3 – firstObject.field3[1]  "b" – secondObject.f1  "val1" – secondObject.f2  "val2" 45 Testing • Don’t use HTML: use Firebug – Open Firebug • F12 or Tools  Firebug  Open Firebug – Go to the ConsoleGo to the Console – Cut/paste the expressions into the command line • Either at the bottom or the right, depending on Options R i d• Reminder – Firebug is indispensible for Ajax development and testing – Download from http://getfirebug.com/Download from http://getfirebug.com/ – For details, see “Ajax Development Tools” section 46
  23. 23. Testing in Firebug: Example • Steps – Opened Firebug with F12 – Cut/pasted code from earlier slide Interactively entered the expressions shown in blue– Interactively entered the expressions shown in blue 47 More on JSON • This section – Constructs JSON explicitly using MVC – Uses normal servlets Reads request parameters as strings– Reads request parameters as strings • Upcoming sections – Constructs JSON automatically from Java objectsConstructs JSON automatically from Java objects – Uses RPC approach to • Hide the use of normal servlets • Pass ordinary arguments instead of request parameter strings • Earlier section (JavaScript Core)( p ) – Gives more examples of basic JSON usage in ordinary JavaScript programs48
  24. 24. © 2010 Marty Hall Handling JSON Data:Handling JSON Data: Examplep Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. Steps • JavaScript – Define an object for sending HTTP requestsDefine an object for sending HTTP requests – Initiate request • Get request object • Designate an anonymous response handler function I iti t POST t t l t• Initiate a POST request to a servlet – Put POST data in the send method – Data based on document.getElementById(id).value of some textfield – Handle responsep • Wait for readyState of 4 and HTTP status of 200 • Extract return text with responseText or responseXML – Add parens then pass string to “eval” to get a real JavaScript object – Access fields array elements etc with normal JavaScript syntaxAccess fields, array elements, etc., with normal JavaScript syntax • Use innerHTML to insert result into designated element • HTML – Load JavaScript from centralized directory – Designate control that initiates request – Give ids to input elements – Define a blank placeholder element with a known id 50
  25. 25. Initiate Request function jsonCityTable(inputField, resultRegion) { var address = "show-cities";var address = show cities ; var data = "cityType=" + getValue(inputField) + "&format=json"; ajaxPost(address dataajaxPost(address, data, function(request) { showJsonCityInfo(request, resultRegion); });}); } 51 Handle Response function showJsonCityInfo(request, resultRegion) { if ((request readyState == 4) &&if ((request.readyState == 4) && (request.status == 200)) { var rawData = request.responseText; var data = eval("(" + rawData + ")");var data eval( ( + rawData + ) ); var table = getTable(data.headings, data.cities); htmlInsert(resultRegion, table); }} } 52
  26. 26. HTML Code ... <fieldset> <legend>Getting JSON Data from Server, Building HTML Table </legend> <form action="#"> <label for="city-type-2">City Type:</label> <select id="city-type-2"> <option value="top-5-cities">Largest Five US Cities</option> <option value="second-5-cities">Second Five US Cities</option> <option value="cities-starting-with-s"> US Cities Starting with 'S'</option> <option value="superbowl-hosts"> Most Recent Superbowl Hosts</option> </select> <br/> <input type="button" value="Show Cities" onclick='jsonCityTable("city-type-2", "json-city-table")'/> </form> <p/> <div id="json-city-table"></div> </fieldset>...53 Server Design: MVC • Logic – No changes to basic logic – Only addition is logic to decide which results page appliesapplies • Presentation – Build a plain-text page instead of an XML pagep p g p g – Embed data in JSON format 54
  27. 27. Servlet Code public class ShowCities extends HttpServlet { public void doGet(HttpServletRequest request,p ( p q q , HttpServletResponse response) throws ServletException, IOException { ... request setAttribute("cities" cities);request.setAttribute("cities", cities); String format = request.getParameter("format"); String outputPage; if ("xml".equals(format)) { response.setContentType("text/xml"); outputPage = "/WEB-INF/results/cities-xml.jsp"; } else if ("json".equals(format)) { response setContentType("application/json");response.setContentType( application/json ); outputPage = "/WEB-INF/results/cities-json.jsp"; } ... RequestDispatcher dispatcher = request.getRequestDispatcher(outputPage); dispatcher.include(request, response); } 55 JSP Code (/WEB-INF/results/cities-json jsp)(/WEB INF/results/cities json.jsp) { headings: ["City", "Time", "Population"], cities: [["${cities[0] name}" "${cities[0] time}"cities: [["${cities[0].name}", "${cities[0].time}", "${cities[0].population}"], ["${cities[1].name}", "${cities[1].time}", "${cities[1].population}"], ["${cities[2].name}", "${cities[2].time}", "${cities[2].population}"], ["${cities[3].name}", "${cities[3].time}", "${cities[3].population}"], ["${cities[4].name}", "${cities[4].time}",[ ${ [ ] } , ${ [ ] } , "${cities[4].population}"]] } 56
  28. 28. JSON Data: Results 57 © 2010 Marty Hall Handling String Data Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
  29. 29. Basic Tasks • General Approach Server side code invents a custom data format– Server-side code invents a custom data format – Client-side code parses it • Specific Common Approach S id d d d li it d t i– Server-side code sends delimited strings – Client-side code uses String.split to break strings into arrays • String.split in JavaScript Q i i il S i li i J– Quite similar to String.split in Java – With a one-char delimiter, use single or double quotes – With a regular expression, use slashes JavaScript regex's similar to Perl (and Java) regular expressions• JavaScript regex's similar to Perl (and Java) regular expressions • More details will be given in a later section • Online references http:// e olt org/article/Reg lar E pressions in Ja aScript/– http://www.evolt.org/article/Regular_Expressions_in_JavaScript/ 17/36435/ – http://www.javascriptkit.com/javatutors/re.shtml 59 String.split: Example 60
  30. 30. © 2010 Marty Hall Handling String Data:Handling String Data: Examplep Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location. Steps • JavaScript – Define an object for sending HTTP requestsDefine an object for sending HTTP requests – Initiate request • Get request object • Designate an anonymous response handler function I iti t POST t t l t• Initiate a POST request to a servlet – Put POST data in the send method – Data based on document.getElementById(id).value of some textfield – Handle responsep • Wait for readyState of 4 and HTTP status of 200 • Extract return text with responseText or responseXML – Break it into array with String.split and regular expression delimiters – Access array elements (perhaps using String split again)Access array elements (perhaps using String.split again) • Use innerHTML to insert result into designated element • HTML – Load JavaScript from centralized directory – Designate control that initiates request – Give ids to input elements – Define a blank placeholder element with a known id 62
  31. 31. Initiate Request function stringCityTable(inputField, resultRegion) { var address = "show-cities";var address = show cities ; var data = "cityType=" + getValue(inputField) + "&format=string"; ajaxPost(address dataajaxPost(address, data, function(request) { showStringCityInfo(request, resultRegion); });}); } 63 Handle Response function showStringCityInfo(request, resultRegion) { if ((request.readyState == 4) &&if ((request.readyState 4) && (request.status == 200)) { var rawData = request.responseText; var rowStrings = rawData.split(/[nr]+/); var headings = rowStrings[0].split("#"); var rows = new Array(rowStrings.length-1); for(var i=1; i<rowStrings.length; i++) { rows[i-1] = rowStrings[i] split("#");rows[i-1] = rowStrings[i].split( # ); } var table = getTable(headings, rows); htmlInsert(resultRegion, table); } } 64
  32. 32. HTML Code ... <fieldset> <legend>Getting String Data from Server, Building HTML Table </legend> <form action="#"> <label for="city-type-3">City Type:</label> <select id="city-type-3"> <option value="top-5-cities">Largest Five US Cities</option> <option value="second-5-cities">Second Five US Cities</option> <option value="cities-starting-with-s"> US Cities Starting with 'S'</option> <option value="superbowl-hosts"> Most Recent Superbowl Hosts</option> </select> <br/> <input type="button" value="Show Cities" onclick='stringCityTable("city-type-3", "string-city-table")'/> </form> <p/> <div id="string-city-table"></div> </fieldset>...65 Server Design: MVC • Logic – No changes to basic logic – Only addition is logic to decide which results page appliesapplies • Presentation – Build a plain-text pagep p g – Embed data between delimiters 66
  33. 33. Servlet Code public class ShowCities extends HttpServlet { public void doGet(HttpServletRequest request,p ( p q q , HttpServletResponse response) throws ServletException, IOException { ... if ("xml" equals(format)) {if ("xml".equals(format)) { response.setContentType("text/xml"); outputPage = "/WEB-INF/results/cities-xml.jsp"; } else if ("json".equals(format)) { response.setContentType("application/json"); outputPage = "/WEB-INF/results/cities-json.jsp"; } else { response setContentType("text/plain");response.setContentType( text/plain ); outputPage = "/WEB-INF/results/cities-string.jsp"; } RequestDispatcher dispatcher = request.getRequestDispatcher(outputPage); dispatcher.include(request, response); } 67 JSP Code (/WEB-INF/results/cities-string jsp)(/WEB INF/results/cities string.jsp) City#Time#Population ${cities[0] name}#${cities[0] time}#${cities[0] population}${cities[0].name}#${cities[0].time}#${cities[0].population} ${cities[1].name}#${cities[1].time}#${cities[1].population} ${cities[2].name}#${cities[2].time}#${cities[2].population} ${cities[3].name}#${cities[3].time}#${cities[3].population}${cities[3].name}#${cities[3].time}#${cities[3].population} ${cities[4].name}#${cities[4].time}#${cities[4].population} 68
  34. 34. String Data: Results 69 © 2010 Marty Hall Combination Data Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
  35. 35. Idea • Earlier – Server • Decided what datatype to return based on “format” parameterp – Client • Hardcoded “format” value • Hardcoded response handler function• Hardcoded response handler function • Now – ServerServer • No change. Still uses “format” param in same way. – Client G t “f t” l f b b• Gets “format” value from combobox • Decides on response handler function based on combobox value71 JavaScript function cityTable(cityTypeField, formatField, resultRegion) { dd h i ivar address = "show-cities"; var cityType = getValue(cityTypeField); var format = getValue(formatField); var data = "cityType=" + cityType + "&format=" + format;"&format=" + format; var responseHandler = findHandler(format); ajaxPost(address, data, function(request) { responseHandler(request resultRegion);responseHandler(request, resultRegion); }); } function findHandler(format) {function findHandler(format) { if (format == "xml") { // == is ok for strings! return(showXmlCityInfo); } else if (format == "json") { return(showJsonCityInfo);y } else { return(showStringCityInfo); } }72
  36. 36. HTML <fieldset> <legend>Choosing Server Datatype...</legend> <form action="#"> <label for="city-type-4">City Type:</label> <select id="city-type-4"> <option value="top-5-cities">Largest Five ...</option> ... </select> <label for="data-type">Server Data Type:</label> <select id="data-type"> ti l " l" l t d " l t d" / ti<option value="xml" selected="selected">XML</option> <option value="json">JSON</option> <option value="string">String</option> </select> <b /><br/> <input type="button" value="Show Cities" onclick='cityTable("city-type-4", "data-type", "city-table")'/> </f ></form> <p/> <div id="city-table"></div> </fieldset>73 Server-Side Code • No changes whatsoever 74
  37. 37. Combination Data: Results 75 © 2010 Marty Hall Wrap-up Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.
  38. 38. Preview of Next Sections • Problems with JSP pages in this section – Repeated identical information for each of the five entries in the list of cities – Cannot handle city lists that are not five entries long– Cannot handle city lists that are not five entries long • Servlet code was independent of the number of cities • Client-side (JavaScript) code was independent of the number of citiesnumber of cities • But JSP code was hard-coded to the number of cities • Handling variable-length data in JSPg g – Bean – Custom tag l– JSTL loop – Scripting loop 77 Preview of Next Sections (Continued)(Continued) • Design – Returning real City objects instead of strings is more in keeping with data-centric approach • Automatic JSON generation• Automatic JSON generation – Building JSON objects automatically from various Java data typesyp • RPC mechanism – Let client side code act as if it is calling a server-side f i ( URL)function (not a URL) – Let client side code pass and receive regular arguments – Let server-side code pass and receive regular argumentsLet server-side code pass and receive regular arguments • Return results converted with JSONObject & JSONArray 78
  39. 39. Summary • Parsing XML data – Call request.responseXML – Call getElementsByTagName Get body text via someElement firstChild nodeValue– Get body text via someElement.firstChild.nodeValue • Parsing JSON data – Add parensAdd parens – Pass to eval – Treat as normal JavaScript object • Parsing string data – Use String.split and (possibly) regular expressions • Server – Use MVC 79 © 2010 Marty Hall Questions? Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, JSF 1.x, JSF 2.0, Struts, Ajax, GWT 2.0, GXT, Spring, Hibernate/JPA, Java 5, Java 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.

×