Tải bản đầy đủ - 0 (trang)
Hack 34. Fetch a Postal Code

Hack 34. Fetch a Postal Code

Tải bản đầy đủ - 0trang

Whentheuserchoosesastatefromthepop-uplist,the

applicationcodesendsthecityandstatetotheserver

component,butonlyifthecityfieldcontainscontent(theuser

couldleaveitemptybymistake).Hereiswhatthewebpage's

codelookslike:




"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtm




PostalCodeSearch





Pleaseenterthecityandstate







City:

State:

Alabama

Alaska

Arizona

Arkansas



California

Colorado







Zipcode:













ThewebpageimportstwoJavaScriptfiles,http_request.jsand

hacks3_6b.js.http_request.js(see"UseYourOwnLibraryfor

XMLHttpRequest"[Hack#3])isresponsibleforsettingupand

usingXMLHttpRequest.ThisfilecontainsthehttpRequest()function

thathacks3_6b.jsuses.Thecodeinhacks3_6b.jshandlesthe

user'sclicksonthepop-uplist,sendsarequestwiththecity

andstatevalues,andthendisplaysthereturnedZIPCodein

thezip5textfield.Hereisthecodeinhacks3_6b.js:



window.onload=function(){

varsts=document.getElementById("sts");

sts.onclick=function(){

varcit=document.getElementById("city");

//Onlymakearequestifthecitytextfield

//hasavalue

if(cit.value){getZipcode(cit.value,sts.value.toUpperCa

};

};



functiongetZipcode(_ct,_st){

if(_ct.length>0&&_st.length>0){

httpRequest("GET","http://www.parkerriver.com/s/zip?cit



encodeURIComponent(_ct)+"&state="+

encodeURIComponent(_st),

true,handleResponse);

}else{

document.getElementById("zip5").value="";

}

}



functionhandleResponse(){

varxmlReturnVal;

try{

if(request.readyState==4){

if(request.status==200){

xmlReturnVal=request.responseXML;

if(xmlReturnVal!=null){

varzip5=xmlReturnVal.getElementsByTagName(

if(zip5&&zip5.childNodes.length>0){

document.getElementById("zip5").

value=zip5.childNodes[0].data;

}

}

}else{

//request.statusis503

//iftheapplicationisn'tavailable;

//500iftheapplicationhasabug

alert(

"Aproblemoccurredwithcommunicating

"theXMLHttpRequestobjectandtheser

}

}//endouterif

}catch(err){

alert("Itdoesnotappearthattheserver"+

"isavailableforthisapplication.Please"+

"tryagainverysoon.\\nError:"+err.message);

}

}



You'veprobablyencounteredthiswindow.onloadeventhandlerin

otherhacks.It'san"eventhandlerthatsetsupanotherevent

handler."Whenthebrowsercompletesloadingthewebpage,

window.onloadspecifieswhathappenswhentheusermakesa

selectionfromthepop-uplistdisplayingtheU.S.states:



window.onload=function(){

varsts=document.getElementById("sts");

sts.onclick=function(){

varcit=document.getElementById("city");

//Onlymakearequestifthecitytextfield

//hasavalue

if(cit.value){getZipcode(cit.value,sts.value.toUpperCa

};

};



ThecodegetsthevalueofthecitytextfieldandtheU.S.states

pop-up,thencallsgetZipCode().Thisfunctionputstogetherthe

URLthatwillconnectsthisapplicationtotheservercomponent.

ThecodethencallsthehttpRequest()functiontofetchtheZIP

Code:



httpRequest("GET","http://localhost:8080/parkerriver/s/zip?city

encodeURIComponent(_ct)+"&state="+

encodeURIComponent(_st),

true,handleResponse);



Again,httpRequest()isdefinedinhttp_request.js.



Server,TakeOver

Theservercomponenthastoconnectwiththewebservice,

whichsendsbackalargeXMLfilecontainingalltheZIPCodes

foraspecificstate.Youhavetouseyourownserver

intermediarybecauseoftheXMLHttpRequestrestrictionon

connectingwithahostthatisdifferentfromthehostfrom

whichtheuserdownloadedthewebpage.



Thisparticularwebservice,whichisgenerouslymadeavailabletoour

code,doesnothaveanoperationthatreturnsjustaZIPCodein

responsetoacityandstatename.Therefore,youhavetotakethis

extrasteptogleantheZIPCodefromtheXMLfile.



ThewebservicereturnsanXMLfilethatlookslikethis:





Abington

MA

02351

781

E





Accord

MA

02018

781

E



...





TheservercomponentusestheSimpleAPIforXML(SAX)to

parsethisreturnvalue.WhentheJavacomponentfindsthecity

nametheuserprovided,itpullsouttheassociatedZIPCode

andsendsittoourAjaxapplicationintheform02351.

ThehandleResponse()functionthenmakessurethisvalueis

placedintheZIPCoderelatedtextfield.Itallhappensquite

fast,consideringthecomplexityinvolved!

HereisasnippetfromhandleResponse():

if(request.status==200){

xmlReturnVal=request.responseXML;

if(xmlReturnVal!=null){

varzip5=xmlReturnVal.getElementsByTagName("zip")[0];

if(zip5&&zip5.childNodes.length>0){

document.getElementById("zip5").

value=zip5.childNodes[0].data;

}

}



ApropertyoftherequestobjectcalledresponseXMLstoresthe

returnedZIPCode,whichisencapsulatedinatag.The

codexmlReturnVal.getElementsByTagName("zip")[0]returnsthetag

holdingtheZIPCode.Thelastlineofthecodesamplethen

storestheZIPCodeinthetextfieldwithidzip5.



TheServlet

Asmentionedearlier,theapplicationcannotconnectdirectly

withthewebserviceusingXMLHttpRequestbecauseourwebpage

hasadifferenthostthanthewebservice'shost.Asafinalstep,

let'slookattheJavaservletthatactsastheintermediary



betweenthewebserviceandtheAjaxcode.Itsiftsthroughall

theZIPCodesforacertainstateandreturnsthefirstZIPCode

itfindsthatisassociatedwiththespecifiedcity(thisisa

potentialflawintheapplication,assomecitiescanhave

multipleZIPCodes):

packagecom.parkerriver;

importjava.net.*;

importjava.io.*;

importjavax.servlet.*;

importjavax.servlet.http.*;

importjavax.xml.parsers.*;

importorg.apache.log4j.*;

importorg.xml.sax.helpers.DefaultHandler;

importorg.xml.sax.*;

publicclassZipServlet2extendsHttpServlet{

privateLoggerlog=null;

privateStringzipCode=null;

publicStringgetZipCode(){

returnzipCode;

}

publicvoidsetZipCode(StringzipCode){

this.zipCode=zipCode;

}



privatestaticStringwsUrl=

"http://www.webservicex.net/uszip.asmx/GetInfoBySta

publicvoidinit()throwsServletException{

log=Logger.getLogger(ZipServlet2.class);

}



protectedvoiddoGet(HttpServletRequesthttpServletRequest,



HttpServletResponsehttpServletRespons

ServletException,IOException{

Stringstte=httpServletRequest.getParameter("state");

String_city=httpServletRequest.getParameter("city");

Stringresp=null;

if(stte!=null&&_city!=null){

URLusps=newURL(wsUrl+stte);

HttpURLConnectionusp=(HttpURLConnection)usps.

openConnection();

usp.setRequestMethod("GET");

usp.setDoInput(true);

usp.connect();



BufferedReaderin=newBufferedReader(

newInputStreamReader(

usp.getInputStream()));

StringBufferbuf=newStringBuffer("");

StringinputLine;

while((inputLine=in.readLine())!=null){

buf.append(inputLine);}

in.close();

resp=buf.toString();

try{

getZipSax(resp,_city);

resp=""+this.getZipCode()+"";

}catch(ParserConfigurationExceptione){

e.printStackTrace();

}

}else{

resp="";

}

httpServletResponse.setContentType("text/xml;charset=U

//Conveytotheuseragentorbrowserthatitshould

//notcachetheresponses

httpServletResponse.setHeader("Cache-Control","no-cach

httpServletResponse.getWriter().write(resp);

}



protectedvoiddoPost(HttpServletRequesthttpServletRequest

HttpServletResponsehttpServletRespon

ServletException,IOException{

doGet(httpServletRequest,httpServletResponse);

}

/*ParsetheXMLfileofzipcodesusingourownDefaultHandler

theContentHandlerthenameofthecitytheuserprovided.*/

privatevoidgetZipSax(StringzipXML,String_city)

throwsParserConfigurationException,IOException{

try{

SAXParserparser=SAXParserFactory.

newInstance().newSAXParser();

parser.parse(newInputSource(newStringReader(zipXM

newMyHandler(_city));

}catch(SAXExceptionsxe){

log.info("CaughtSAXException:"+sxe.getMessage()

}



}

/*ASAXContentHandlerthatparsesanXMLfile;itsetsth

parentclass'szipCodepropertywhenitfindsthecorrectz

codeintheXML,thenthrowsaSAXExceptiontohaltthepar

classMyHandlerextendsDefaultHandler{

privateStringcity;

privatebooleanfoundCityFlag,foundCityVal,foundZipFlag

publicMyHandler(){

super();

}

publicMyHandler(String_city){

this();

this.city=_city;

}

publicvoidstartElement(Stringstring,Stringstring1,

Stringstring2,

Attributesattributes)throwsSAXException{

if(string2.equalsIgnoreCase("city")){



foundCityFlag=true;

}

if(foundCityVal){

if(string2.equalsIgnoreCase("zip")){

foundZipFlag=true;

}

}

}

publicvoidcharacters(char[]chars,inti,

inti1)throwsSAXException{



if(foundCityFlag){

if(newString(chars,i,i1).equalsIgnoreCase(city

foundCityVal=true;

}else{

foundCityFlag=false;

}

}

if(foundZipFlag){

setZipCode(newString(chars,i,i1));

thrownewSAXException("Wefoundthezipcode."

}

}

}

}



TheSAXtechniqueusesacallbackobjectinthiscase,aclass

calledMyHandlertolookforcitytagsthatcontaintheuser's

specifiedcity.TheMyHandlerobjectimplementsaninterfacethat

ispartoftheSAXAPIcalledContentHandler.AContentHandlerlets

theprogrammerdecidewhatshouldhappenastheparsersifts

throughtheXMLstreamatdifferentstages:whenthehandler

findsthebeginningofanXMLelement,thecontentofan



element,theendofanelement,andsoon.

IftheContentHandlerfindsacitytagwhosecontentmatchesthe

user'schosencity,itlooksforanassociatedziptagandgrabs

thevalueofthattag.ItthenthrowsaSAXExceptiontheJavaway

ofsignalingthattheXMLparsingcanstopbecausethecodehas

foundtheZIPCodevalue.



Seehttp://www.saxproject.orgformoreinformationonSAX.



ThisisaniftywaytodisplayZIPCodestotheuserbecause

theygenerallyappearinthetextfieldveryquickly,withoutthe

pagerefreshingorchanginginanyotherway.Theuserjusthas

tocorrectlyspellthecity,chooseastateinthepop-up,and

presto,there'stheZIPCode.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Hack 34. Fetch a Postal Code

Tải bản đầy đủ ngay(0 tr)

×