AnyonewhohasusedFlickr,GMail,GoogleSuggest,orGoogleMapswillrealizethatanewbreedofdynamicwebapplicationsareemerging.Theseapplicationslookandactverysimilartotraditionaldesktopapplicationswithoutrelyingonpluginsorbrowserspecificfeatures.WebapplicationshavetraditionallybeenasetofHtmlpagesthatmustbereloadedtochangeanyportionofthecontent.Overthepastfewyears,technologIEssuchasJavaScriptandCascadingStyleSheet(CSS)havematuredtothepointwheretheycanbeusedeffectivelytocreateverydynamicwebapplicationsthatwillworkonallofthemajorbrowsers.Thisdocumentandthesolutionsassociatedwithitwilldetailseveraltechniquesthatyoucanusetodaytoenableyourwebapplicationstobemorerichandinteractivelikedesktopapplications.
IntroducingAsynchronousJavaScriptandXML(AJax)
UsingJavascriptanHTMLpagecanasynchronouslymakecallstotheserverfromwhichitwasloadedandfetchXMLdocuments.TheXMLdocumentsmaythenbeusedbyJavascripttoupdateormodifytheDocumentObjectModel(DOM)oftheHtmlpage.ThetermAsynchronousJavaScriptandXML(AJax)hasemergedrecentlytodescribethisinteractionmodel.
AJaxisnotnew.ThesetechniqueshavebeenavailabletodeveloperstargetingInternetExplorer(IE)ontheWindowsplatformformanyyears.Upuntilrecentlythetechnologywasreferredtoaswebremotingorremotescripting.Webdevelopershavealsousedacombinationofplugins,Javaapplets,andhiddenframestoemulatethisinteractionmodelforsometime.WhathaschangedrecentlyisthattheinclusionofsupportfortheXMLHttpRequestobjecthasbecameubiquitousinthemainstreambrowsersacrossallplatforms.TherealmagicistheresultoftheJavascriptXMLHttpRequestobject.WhilethisobjectisnotspecifIEdintheformalJavascriptspecification,itissupportedbyallofthemainstreambrowserstoday.WhiletherearesubtledifferenceswiththeJavaScriptandCSSsupportamongcurrentgenerationbrowserssuchasFirefox,IEandSafari,theyaremanageable.Ifyouarerequiredtosupportolderbrowsers,AJaxmaynotbetheanswerforyou.
WhatmakesAJaxbasedclientsuniqueisthattheclIEntcontainspagespecificcontrollogicembeddedasJavascript.ThepageinteractswiththeJavaScriptbasedoneventssuchasthedocumentbeingloaded,amouseclick,focuschanges,orevenatimer.AJAXinteractionsallowfOraclearseparationofpresentationlogicfromthedata.AnHTMLpagecanpullinbitesizepIEcesofdataasneededversusreloadingthewholepageeverytimeachangeneedstobedisplayed.AJaxwillrequireadifferentserver-sidearchitecturetosupportthisinteractionmodel.Traditionally,server-sidewebapplicationshavefocusedongeneratingHTMLdocumentsforeveryclienteventresultinginacalltotheserverandtheclientswouldrefreshandre-renderthecompleteHTMLpageforeachresponse.RichwebapplicationsfocusonaclIEntfetchinganHtmldocumentwhichactsasatemplateorcontainerforinjectingcontentintobasedonclIEnteventsusingXMLdataretrIEvedfromaserver-sidecomponent.
SomeusecasesforAJaxinteractionsare:
RealtimeFormDataValidation:Formdatasuchasuserids,serialnumbers,postalcodes,orevenspecialcouponcodesthatrequireserver-sidevalidationcanbevalidatedinaformbeforetheusersubmitsaform.
Auto-Completion:ASPecificportionofformdatasuchasanemailaddress,name,orcitynamemaybeauto-completedastheusertypes.
MasterDetailsOperations:BasedonaclIEnteventanHtmlpagecanfetchmoredetailedinformationondatasuchasaproductlistingthatenablestheclienttovIEwtheindividualproductinformationwithoutrefreshingthepage.
SophisticatedUserInterfaceControls:Controlssuchastreecontrols,menus,andprogressbarsmaybeprovidedthatdonotrequirepagerefreshes.
RefreshingDataonthePage:Htmlpagesmaypolldatafromaserverforuptodatedatasuchasscores,stockquotes,weather,orapplicationspecficdata.
Server-sideNotifications:AnHtmlpagemaysimulateaserver-sidepushbypollingtheserverforeventnotificationswhichmaynotifytheclientwithamessage,refreshpagedata,orredirecttheclIEnttoanotherpage.
Thislistisnotallinclusive,however,itdoesshowthatAJaxinteractionsallowwebapplicationstodomuchmorethantheyhavetraditionallydoneinthepast.Whilemanyofthesebenefitsarenoteworthytherearesomedrawbackstothisapproachaswell:
Complexity:Server-sidedeveloperswillneedtounderstandthatpresentationlogicwillberequiredintheHTMLclIEntpagesaswellasintheserver-sidelogictogeneratetheXMLcontentneededbytheclIEntHtmlpages.JavaScriptskillsarerequiredfortheHtmlpagedevelopers.OvertimeitwillbecomeeasIErtocreateAJaxenabledapplicationsasnewframeworksarecreatedandexistingframeworksevolvetosupporttheinteractionmodel.
StandardizationoftheXMLHttpRequestObject:TheXMLHttpRequestisnotyetapartoftheJavaScriptspecificationwhichmeansthatthebehaviormayvarydependingontheclIEnt.
JavascriptImplementations:AJaxinteractionsdependheavilyonJavaScriptwhichhassubtledifferencesdependingontheclIEnt(seeQuirksMode.orgformoredetailsonbrowserspecificdifferences.
Debugging:AJaxapplicationsarealsodifficulttodebugbecausetheprocessinglogicisbothembeddedintheclIEntandontheserver.
ViewableSource:TheclIEntsideJavaScriptmaybeviewedbytheclientbysimplyselecting"VIEwSource"formanAJaxenabledHtmlpage.ApoorlydesignedAJaxbasedapplicationcouldopenitselfuptohackersorplagarism.
FrameworksandpatternsforAJAXtechnologyarelikelytoemergeasdevelopersgainmoreexperIEncedwrittingapplicationsthatusetheAJAXinteractionmodel.Itisstillearlytofocusona"onesizefitsall"frameworkforAJAXinteractions.ThisdocumentandtheassociatedsolutionsfocusonhowAJaxinteractionscanbesupportedtodaybyexistingJava2EnterpriseEdition(J2EE)technologIEssuchservlets,JavaServerPages,JavaServerFacesandtheJavaStandardTagLibrarIEs(JSTL).
TheAnatomyofanAJaxinteraction
NowthatwehavediscussedwhatAJAXisandwhatsomehigherlevelissuesare,let'sputallthepIEcestogetherandshowanAJaxenabledJ2EEapplication.
Let'sconsideranexample,awebapplicationcontainsastaticHTMLpageoranHTMLpagegeneratedinJSPtechnologycontainsanHtmlformthatrequiresserver-sidelogictovalidatetoformdatawithoutrefreshingthepage.Aserver-sidewebcomponent(servlet)namedValidateServletwillprovidethevalidationlogic.ThegraphicbelowdescribesthedetailsoftheAJaxinteractionthatwillprovidethevalidationlogic.
TheitemsbelowrepresentthesetupsofanAJaxinteractionastheyappearinthegraphicabove.
AclIEnteventoccurs.
AnXMLHttpRequestobjectiscreatedandinitialized.
TheXMLHttpRequestobjectmakesacall.
TherequestisprocessedbytheValidationServlet.
TheValidationServletreturnsanXMLDocumentcontainingtheresult.
TheXMLHttpRequestobjectcallsthecallback()functionandprocessestheresult.
TheHtmlDOMisupdated.
NowletlookateachstepoftheAJaxinteractioninmoredetail.
1.AclIEnteventoccurs.
JavaScriptfunctionsarecalledastheresultofanevent.Inthecasethefunctionvalidate()maybemappedtoaonkeyupeventonalinkorformcomponent.
size="20" id="userid" name="id" onkeyup="validate();"> Theformelementabovewillcallthevalidate()eachtimeakeyispressedintheformfIEld. 2.AXMLHttpRequestobjectiscreatedandinitialized. AnXMLHttpRequestobjectisinitializedandconfigured. varreq; functionvalidate(){ varidField=document.getElementById("idFIEld"); varurl="validate?id="+escape(idFIEld.value); if(window.XMLHttpRequest){ req=newXMLHttpRequest(); }elseif(window.ActiveXObject){ req=newActiveXObject("Microsoft.XMLHTTP"); } req.open("GET",url,true); req.onreadystatechange=callback; req.send(null); } Thevalidate()functioninitializesaXMLHttpRequestobjectopenmethodrequiresthreeargumentswhicharewithaurlStringofGETorPOSTrepresetingtheHTTPmethodtobeused,aStringforthetargetURL,andabooleanindicatingwhetherornotthecallwillbemadeasynchronously.Ifaninteractionissetasasynchronous(true)acallbackfuctionmustbespecfIEd.Thecallbackfunctionforthisinteractionissetwiththestatementreq.onreadystatechange=callback;.Seethesectiontitled"TheXMLHttpRequestobjectcallsthecallback()functionandprocessestheresult"formoredetails. 3.TheXMLHttpRequestobjectmakesacall. Whenthestatmentreq.send(null);isreachedthecallwillbemade.InthecaSEOfaHTTPgetthiscontentmaybenullorleftblank.WhenthethisfunctioniscalledontheXMLHttpRequestobjectthecalltotheURLthatwassetduringtheinitializationoftheobjectiscalled.InthecaSEOfthisexamplethedatathatisposted(id)isincludedasaURLparameter. UseanHTTPGETwhentherequestisidempotentmeaningthattwoduplicaterequestswillreturnthesameresults.WhenusingHTTPGETmethodthelengthofURLincludingescapedURLparametersislimitedbysomebrowsersandbyserver-sidewebcontainers.TheHTTPPOSTmethodshouldbeusedwhensendingdatatotheserverthatwilleffecttheserver-sideapplicationstate.AHTTPPOSTrequiresaContent-TypeheadertobesetontheXMLHttpRequestobjectbyusingthefollowingstatement: req.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); req.send("id="+escape(idTextFIEld.value)); WhensendingformvaluesfromJavascriptyoushouldtakeintoconsiderationtheencodingofthefIEldvalues.JavaScriptincludesanescape()functionwhichshouldbeusedtoensurelocalizedcontentisencodedproperlyandthatspecialcharachtersareescapedcorrectly. 4.TherequestisprocessedbytheValidationServlet. AservletmappedtotheURI"validate"checksiftheuseridisintheuserdatabSEOrnot. AservletprocessesaXMLHttpRequestjustasitwouldanyotherHTTPrequest.Theexamplebelowshowaserverextractingtheidparameterfromtherequestandvalidatingwhetherornottheparameterhasbeentaken. publicclassValidationServletextendsHttpServlet{ privateServletContextcontext; privateHashMapusers=newHashMap(); publicvoidinit(ServletConfigconfig)throwsServletException{ this.context=config.getServletContext(); users.put("greg","accountdata"); users.put("duke","accountdata"); } publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse) throwsIOException,ServletException{ StringtargetId=request.getParameter("id"); if((targetId!=null)&&!users.containsKey(targetId.trim())){ response.setContentType("text/XML"); response.setHeader("Cache-Control","no-cache"); response.getWriter().write("valid"); }else{ response.setContentType("text/XML"); response.setHeader("Cache-Control","no-cache"); response.getWriter().write("invalid"); } } } InthisexampleasimpleHashMapisusedtocontaintheusers.InthecaSEOfthisexampleletusassumetheuserid"duke"wassubmitted. 5.TheValidationServletreturnsanXMLDocument. Theuserid"duke"ispresentinthelistofuseridsintheusersHashMap.TheValidationServletwillwriteaXMLdocumenttotheresponsecontainingan"message"elementwiththevalueof"invalid".MorecomplexusecasesmayrequireDOM,XSLT,orotherAPIstogeneratetheresponse. response.setContentType("text/XML"); response.setHeader("Cache-Control","no-cache"); response.getWriter().write("invalid"); TwothingsthatadeveloperneedstobeawareofisthattheContent-Typeissetto"text/xml"andtheCache-Controlneedstobesetto"no-cache".TheXMLHttpRequestobjectwillonlyprocessrequeststhatareoftheContent-Typeof"text/XML"andtheCache-Controlbeingsetto"no-cache"willkeepbrowsersfromlocallycachingresponsesforcaseswhereduplicaterequestsforthesameURL(includingURLparameters)mayreturndifferentresponses. 6.TheXMLHttpRequestobjectcallsthecallback()functionandprocessestheresult. TheXMLHttpRequestobjectwasconfiguredtocallthecallback()functionwhentherearechangestothereadyStateoftheXMLHttpRequestobject.LetusassumethecalltotheValidationServletwasmadeandthereadyStateis"4"signifyingtheXMLHttpRequestcalliscomplete.TheHTTPstatuscodeof"200"signifIEsasuccessfulHTTPinteraction. functioncallback(){ if(req.readyState==4){ if(req.status==200){ //updatetheHtmlDOMbasedonwhetherornotmessageisvalid } } } Browsersmaintainanobjectrepresentationofthedocumentsbeingdisplayed(referredtoasthedocumentobjectmodel(DOM)).JavascriptinanHtmlpagehasAccesstotheDOMandAPIsareavailablethatallowJavaScripttomodifytheDOMafterthepagehasloaded. Followingasuccessfulrequest,JavaScriptcodemaymodifytheDOMoftheHTMLpage.TheobjectrepresentationoftheXMLdocumentthatwasretrIEvedfromtheValidationServletisavailabletoJavascriptcodeusingthereq.responseXMLwherereqisanXMLHttpRequestobject.TheDOMAPIsprovideameansforJavascripttonavigatethecontentfromthatdocumentandusethatcontenttomodifytheDOMoftheHtmlpage.AstringrepresentationofthedocumentthatwasretrIEvedbycallingreq.responseText.NowletuslookatthehowtousetheDOMAPIsinJavaScriptbylookingatthefollowingXMLdocumentreturnedfromtheValidateServlet. valid TheexampleaboveisasimpleXMLfragmentthatcontainsthesenderofthemessageelementwhichissimplythestring"valid"or"invalid".Amoreadvancedsamplemaycontainmorethanonemessageandvalidnamesthatmightbepresentedtotheuser. functionparseMessage(){ varmessage=req.responseXML.getElementsByTagName("message")[0]; setMessage(message.childNodes[0].nodeValue); } TheparseMessages()functionwillprocessXMLdocumentretrIEvedfromtheValidationServlet.ThisfunctionwillcallthesetMessage()withvalueofthemessageelementtoupdatetheHtmlDOM. 7.TheHtmlDOMisupdated. JavascriptcangainareferencetoanyelementintheHTMLDOMusinganumberofAPIs.Therecommendedwaytogainareferencetoaelementistocalldocument.getElementById("userIdMessage")where"userIdMessage"istheidattributeofanelementappearingintheHtmldocument.WithareferencetotheelementJavaScriptmaynowbeusedtomaybemodifyattributesoftheelement,modifythestylepropertIEsofelement,oraddorremove,modifychildelements. OnecommonmeanstochangethebodycontentofanelementistosettheinnerHtmlpropertyontheelementascanbeseeninthefollowingexample. TheportionsoftheHTMLpagethatwereaffectedarere-renderedimmediatelyfollowingthesettingoftheinnerHTML.IftheinnerHtmlpropertycontainselementssuchasor