这些时间,瞎子也看得见,AJAX正大踏步的朝我们走来。不管我们是拥护也好,反对也罢,还是视而不见,AJAX像一阵潮流,席转了我们所有的人。关于AJAX的定义也好,大话也好,早有人在网上发表了汗牛充栋的文字,在这里我也不想照本宣科。只想说说我感觉到的一些优点,对于不对,大家也可以和我讨论:首先是异步交互,用户感觉不到页面的提交,当然也不等待页面返回。这是使用了AJAX技术的页面给用户的第一感觉。其次是响应速度快,这也是用户强烈体验。然后是与我们开发者相关的,复杂UI的成功处理,一直以来,我们对B/S模式的UI不如C/S模式UI丰富而苦恼。现在由于AJAX大量使用JS,使得复杂的UI的设计变得更加成功。最后,AJAX请求的返回对象为XML文件,这也是一个潮流,就是WEBSERVICE潮流一样。易于和WEBSERVICE结合起来。好了,闲话少说,让我们转入正题吧。我们的第一个例子是基于Servlet为后台的一个web应用。基于Servlet的AJAX这是一个很常见的UI,当用户在第一个选择框里选择ZHEJIANG时,第二个选择框要出现ZHEJIANG的城市;当用户在第一个选择框里选择JIANGSU时,第二个选择框里要出现JIANGSU的城市。首先,我们来看配置文件web.xml,在里面配置一个servlet,跟往常一样:web-appversion=2.4xmlns=:xsi=:schemaLocation=://java.sun.com/xml/ns/j2ee/web-app_2_4.xsdservletservlet-nameSelectCityServlet/servlet-nameservlet-classcom.stephen.servlet.SelectCityServlet/servlet-class/servletservlet-mappingservlet-nameSelectCityServlet/servlet-nameurl-pattern/servlet/SelectCityServlet/url-pattern/servlet-mapping/web-app然后,来看我们的JSP文件:!DOCTYPEHTMLPUBLIC-//W3C//DTDHTML4.01Transitional//ENhtmlheadtitleMyHtml.html/titlemetahttp-equiv=keywordscontent=keyword1,keyword2,keyword3metahttp-equiv=descriptioncontent=thisismypage!--linkrel=stylesheettype=text/csshref=./styles.css--/headscripttype=text/javascriptfunctiongetResult(stateVal){varurl=servlet/SelectCityServlet?state=+stateVal;if(window.XMLHttpRequest){req=newXMLHttpRequest();}elseif(window.ActiveXObject){req=newActiveXObject(Microsoft.XMLHTTP);}if(req){req.open(GET,url,true);req.onreadystatechange=complete;req.send(null);}}functioncomplete(){if(req.readyState==4){if(req.status==200){varcity=req.responseXML.getElementsByTagName(city);file://alert(city.length);varstr=newArray();for(vari=0;icity.length;i++){str[i]=city[i].firstChild.data;}file://alert(document.getElementById(city));buildSelect(str,document.getElementById(city));}}}functionbuildSelect(str,sel){sel.options.length=0;for(vari=0;istr.length;i++){sel.options[sel.options.length]=newOption(str[i],str[i])}}/scriptbodyselectname=stateonChange=getResult(this.value)optionvalue=Select/optionoptionvalue=zjZEHJIANG/optionoptionvalue=zsJIANGSU/option/selectselectid=cityoptionvalue=CITY/option/select/body/html第一眼看来,跟我们平常的JSP没有两样。仔细一看,不同在JS里头。我们首先来看第一个方法:getResult(stateVal),在这个方法里,首先是取得XmlHttpRequest;然后设置该请求的url:req.open(GET,url,true);接着设置请求返回值的接收方法:req.onreadystatechange=complete;该返回值的接收方法为——complete();最后是发送请求:req.send(null);然后我们来看我们的返回值接收方法:complete(),这这个方法里,首先判断是否正确返回,如果正确返回,用DOM对返回的XML文件进行解析。关于DOM的使用,这里不再讲述,请大家参阅相关文档。得到city的值以后,再通过buildSelect(str,sel)方法赋值到相应的选择框里头去。最后我们来看看Servlet文件:importjava.io.IOException;importjava.io.PrintWriter;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;/***@authorAdministrator**TODOTochangethetemplateforthisgeneratedtypecommentgoto*Window-Preferences-Java-CodeStyle-CodeTemplates*/publicclassSelectCityServletextendsHttpServlet{publicSelectCityServlet(){super();}publicvoiddestroy(){super.destroy();}publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType(text/xml);response.setHeader(Cache-Control,no-cache);Stringstate=request.getParameter(state);StringBuffersb=newStringBuffer(state);if(zj.equals(state)){sb.append(cityhangzhou/citycityhuzhou/city);}elseif(zs.equals(state)){sb.append(citynanjing/citycityyangzhou/citycitysuzhou/city);}sb.append(/state);PrintWriterout=response.getWriter();out.write(sb.toString());out.close();}}这个类也十分简单,首先是从request里取得state参数,然后根据state参数生成相应的XML文件,最后将XML文件输出到PrintWriter对象里。到现在为止,第一个例子的代码已经全部结束。是不是比较简单?运行图:/!DOCTYPEhtmlPUBLIC-//W3C//DTDHTML4.01Transitional//ENhtmlheadmetahttp-equiv=Content-typecontent=text/html;charset=utf-8title多级联动菜单/titlescripttype=text/javascriptvarxmlHttp;//用于保存XMLHttpRequest对象的全局变量vartargetSelId;//用于保存要更新选项的列表idvarselArray;//用于保存级联菜单id的数组//用于创建XMLHttpRequest对象functioncreateXmlHttp(){//根据window.XMLHttpRequest对象是否存在使用不同的创建方式if(window.XMLHttpRequest){xmlHttp=newXMLHttpRequest();//FireFox、Opera等浏览器支持的创建方式}else{xmlHttp=newActiveXObject(Microsoft.XMLHTTP);//IE浏览器支持的创建方式}}//获取列表选项的调用函数functionbuildSelect(selectedId,targetId){if(selectedId==){//selectedId为空串表示选中了默认项clearSubSel(targetId);//清除目标列表及下级列表中的选项return;//直接结束函数调用,不必向服务器请求信息}targetSelId=targetId;//将传入的目标列表id赋值给targetSelId变量createXmlHttp();//创建XmlHttpRequest对象xmlHttp.onreadystatechange=buildSelectCallBack;//设置回调函数xmlHttp.open(GET,select_menu.jsp?selectedId=+selectedId,true);xmlHttp.send(null);}//获取列表选项的回调函数functionbuildSelectCallBack(){if(xmlHttp.readyState==4){varoptionsInfo=eval((+xmlHttp.responseText+));//将从服务器获得的文本转为对象直接量vartargetSelNode=document.getElementById(targetSelId);clearSubSel(targetSelId);//清除目标列表中的选项//遍历对象直接量中的成员for(varoinoptionsInfo){targetSelNode.appendChild(createOption(o,option