Ajax构建动态的 Java 应用程序.docx

上传人:b****6 文档编号:13332455 上传时间:2023-06-13 格式:DOCX 页数:16 大小:42.75KB
下载 相关 举报
Ajax构建动态的 Java 应用程序.docx_第1页
第1页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第2页
第2页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第3页
第3页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第4页
第4页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第5页
第5页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第6页
第6页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第7页
第7页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第8页
第8页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第9页
第9页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第10页
第10页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第11页
第11页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第12页
第12页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第13页
第13页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第14页
第14页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第15页
第15页 / 共16页
Ajax构建动态的 Java 应用程序.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Ajax构建动态的 Java 应用程序.docx

《Ajax构建动态的 Java 应用程序.docx》由会员分享,可在线阅读,更多相关《Ajax构建动态的 Java 应用程序.docx(16页珍藏版)》请在冰点文库上搜索。

Ajax构建动态的 Java 应用程序.docx

Ajax构建动态的Java应用程序

面向Java开发人员的Ajax:

构建动态的Java应用程序

Ajax为更好的Web应用程序铺平了道路

级别:

中级

PhilipMcCarthy,软件开发顾问,独立咨询顾问

2005年10月20日

在Web应用程序开发中,页面重载循环是最大的一个使用障碍,对于Java™开发人员来说也是一个严峻的挑战。

在这个系列中,作者PhilipMcCarthy介绍了一种创建动态应用程序体验的开创性方式。

Ajax(异步JavaScript和XML)是一种编程技术,它允许为基于Java的Web应用程序把Java技术、XML和JavaScript组合起来,从而打破页面重载的范式。

Ajax(即异步JavaScript和XML)是一种Web应用程序开发的手段,它采用客户端脚本与Web服务器交换数据。

所以,不必采用会中断交互的完整页面刷新,就可以动态地更新Web页面。

使用Ajax,可以创建更加丰富、更加动态的Web应用程序用户界面,其即时性与可用性甚至能够接近本机桌面应用程序。

Ajax不是一项技术,而更像是一个模式——一种识别和描述有用的设计技术的方式。

Ajax是新颖的,因为许多开发人员才刚刚开始知道它,但是所有实现Ajax应用程序的组件都已经存在若干年了。

它目前受到重视是因为在2004和2005年出现了一些基于Ajax技术的非常棒的动态WebUI,最著名的就是Google的GMail和Maps应用程序,以及照片共享站点Flickr。

这些用户界面具有足够的开创性,有些开发人员称之为“Web2.0”,因此对Ajax应用程序的兴趣飞速上升。

在这个系列中,我将提供使用Ajax开发应用程序需要的全部工具。

在第一篇文章中,我将解释Ajax背后的概念,演示为基于Java的Web应用程序创建Ajax界面的基本步骤。

我将使用代码示例演示让Ajax应用程序如此动态的服务器端Java代码和客户端JavaScript。

最后,我将指出Ajax方式的一些不足,以及在创建Ajax应用程序时应当考虑的一些更广的可用性和访问性问题。

更好的购物车

可以用Ajax增强传统的Web应用程序,通过消除页面装入从而简化交互。

为了演示这一点,我采用一个简单的购物车示例,在向里面添加项目时,它会动态更新。

这项技术如果整合到在线商店,那么用户可以持续地浏览和向购物车中添加项目,而不必在每次点击之后都等候完整的页面更新。

虽然这篇文章中的有些代码特定于购物车示例,但是演示的技术可以应用于任何Ajax应用程序。

清单1显示了购物车示例使用的有关HTML代码,整篇文章中都会使用这个HTML。

清单1.购物车示例的有关片断

--Tableofproductsfromstore'scatalog,onerowperitem-->

NameDescriptionPrice

...

--Itemdetails-->

HatStylishbowlerhat$19.99

--ClickbuttontoadditemtocartviaAjaxrequest-->

AddtoCart

...

--Representationofshoppingcart,updatedasynchronously-->

--List-itemswillbeaddedhereforeachiteminthecart-->

--Totalcostofitemsincartdisplayedinsidespanelement-->

Totalcost:

$0.00

Ajax往返过程

Ajax交互开始于叫作XMLHttpRequest的JavaScript对象。

顾名思义,它允许客户端脚本执行HTTP请求,并解析XML服务器响应。

Ajax往返过程的第一步是创建XMLHttpRequest的实例。

在XMLHttpRequest对象上设置请求使用的HTTP方法(GET或POST)以及目标URL。

现在,您还记得Ajax的第一个a是代表异步(asynchronous)吗?

在发送HTTP请求时,不想让浏览器挂着等候服务器响应。

相反,您想让浏览器继续对用户与页面的交互进行响应,并在服务器响应到达时再进行处理。

为了实现这个要求,可以在XMLHttpRequest上注册一个回调函数,然后异步地分派XMLHttpRequest。

然后控制就会返回浏览器,当服务器响应到达时,会调用回调函数。

在JavaWeb服务器上,请求同其他HttpServletRequest一样到达。

在解析了请求参数之后,servlet调用必要的应用程序逻辑,把响应序列化成XML,并把XML写入HttpServletResponse。

回到客户端时,现在调用注册在XMLHttpRequest上的回调函数,处理服务器返回的XML文档。

最后,根据服务器返回的数据,用JavaScript操纵页面的HTMLDOM,把用户界面更新。

图1是Ajax往返过程的顺序图。

图1.Ajax往返过程

现在您对Ajax往返过程有了一个高层面的认识。

下面我将放大其中的每一步骤,进行更详细的观察。

如果过程中迷了路,请回头看图1——由于Ajax方式的异步性质,所以顺序并非十分简单。

分派XMLHttpRequest

我将从Ajax序列的起点开始:

创建和分派来自浏览器的XMLHttpRequest。

不幸的是,不同的浏览器创建XMLHttpRequest的方法各不相同。

清单2的JavaScript函数消除了这些依赖于浏览器的技巧,它可以检测当前浏览器要使用的正确方式,并返回一个可以使用的XMLHttpRequest。

最好是把它当作辅助代码:

只要把它拷贝到JavaScript库,并在需要XMLHttpRequest的时候使用它就可以了。

清单2.创建跨浏览器的XMLHttpRequest

/*

*ReturnsanewXMLHttpRequestobject,orfalseifthisbrowser

*doesn'tsupportit

*/

functionnewXMLHttpRequest(){

varxmlreq=false;

if(window.XMLHttpRequest){

//CreateXMLHttpRequestobjectinnon-Microsoftbrowsers

xmlreq=newXMLHttpRequest();

}elseif(window.ActiveXObject){

//CreateXMLHttpRequestviaMSActiveX

try{

//TrytocreateXMLHttpRequestinlaterversions

//ofInternetExplorer

xmlreq=newActiveXObject("Msxml2.XMLHTTP");

}catch(e1){

//FailedtocreaterequiredActiveXObject

try{

//Tryversionsupportedbyolderversions

//ofInternetExplorer

xmlreq=newActiveXObject("Microsoft.XMLHTTP");

}catch(e2){

//UnabletocreateanXMLHttpRequestwithActiveX

}

}

}

returnxmlreq;

}

稍后我将讨论处理那些不支持XMLHttpRequest的浏览器的技术。

目前,示例假设清单2的newXMLHttpRequest函数总能返回XMLHttpRequest实例。

返回示例的购物车场景,我想要当用户在目录项目上点击AddtoCart时启动Ajax交互。

名为addToCart()的onclick处理函数负责通过Ajax调用来更新购物车的状态(请参阅清单1)。

正如清单3所示,addToCart()需要做的第一件事是通过调用清单2的newXMLHttpRequest()函数得到XMLHttpRequest对象。

接下来,它注册一个回调函数,用来接收服务器响应(我稍后再详细解释这一步;请参阅清单6)。

因为请求会修改服务器上的状态,所以我将用HTTPPOST做这个工作。

通过POST发送数据要求三个步骤。

第一,需要打开与要通信的服务器资源的POST连接——在这个示例中,服务器资源是一个映射到URLcart.do的servlet。

然后,我在XMLHttpRequest上设置一个头,指明请求的内容是表单编码的数据。

最后,我用表单编码的数据作为请求体发送请求。

清单3把这些步骤放在了一起。

清单3.分派AddtoCartXMLHttpRequest

/*

*Addsanitem,identifiedbyitsproductcode,totheshoppingcart

*itemCode-productcodeoftheitemtoadd.

*/

functionaddToCart(itemCode){

//ObtainanXMLHttpRequestinstance

varreq=newXMLHttpRequest();

//Setthehandlerfunctiontoreceivecallbacknotifications

//fromtherequestobject

varhandlerFunction=getReadyStateHandler(req,updateCart);

req.onreadystatechange=handlerFunction;

//OpenanHTTPPOSTconnectiontotheshoppingcartservlet.

//Thirdparameterspecifiesrequestisasynchronous.

req.open("POST","cart.do",true);

//Specifythatthebodyoftherequestcontainsformdata

req.setRequestHeader("Content-Type",

"application/x-www-form-urlencoded");

//SendformencodeddatastatingthatIwanttoaddthe

//specifieditemtothecart.

req.send("action=add&item="+itemCode);

}

这就是建立Ajax往返过程的第一部分,即创建和分派来自客户机的HTTP请求。

接下来是用来处理请求的Javaservlet代码。

servlet请求处理

用servlet处理XMLHttpRequest,与处理普通的浏览器HTTP请求一样。

可以用HttpServletRequest.getParameter()得到在POST请求体中发送的表单编码数据。

Ajax请求被放进与来自应用程序的常规Web请求一样的HttpSession中。

对于示例购物车场景来说,这很有用,因为这让我可以把购物车状态封装在JavaBean中,并在请求之间在会话中维持这个状态。

清单4是处理Ajax请求、更新购物车的简单servlet的一部分。

Cartbean是从用户会话中获得的,并根据请求参数更新它的状态。

然后Cart被序列化成XML,XML又被写入ServletResponse。

重要的是把响应的内容类型设置为application/xml,否则XMLHttpRequest不会把响应内容解析成XMLDOM。

清单4.处理Ajax请求的servlet代码

publicvoiddoPost(HttpServletRequestreq,HttpServletResponseres)

throwsjava.io.IOException{

Cartcart=getCartFromSession(req);

Stringaction=req.getParameter("action");

Stringitem=req.getParameter("item");

if((action!

=null)&&(item!

=null)){

//AddorremoveitemsfromtheCart

if("add".equals(action)){

cart.addItem(item);

}elseif("remove".equals(action)){

cart.removeItems(item);

}

}

//SerializetheCart'sstatetoXML

StringcartXml=cart.toXml();

//WriteXMLtoresponse.

res.setContentType("application/xml");

res.getWriter().write(cartXml);

}

清单5显示了Cart.toXml()方法生成的示例XML。

它很简单。

请注意cart元素的generated属性,它是System.currentTimeMillis()生成的一个时间戳。

清单5.Cart对象的XML序列化示例

xmlversion="1.0"?

>

Hat

2

Chair

1

Dog

1

如果查看应用程序源代码(可以从下载一节得到)中的Cart.java,可以看到生成XML的方式只是把字符串添加在一起。

虽然对这个示例来说足够了,但是对于从Java代码生成XML来说则是最差的方式。

我将在这个系列的下一期中介绍一些更好的方式。

现在您已经知道了CartServlet响应XMLHttpRequest的方式。

下一件事就是返回客户端,查看如何用XML响应更新页面状态。

用JavaScript进行响应处理

XMLHttpRequest的readyState属性是一个数值,它指出请求生命周期的状态。

它从0(代表“未初始化”)变化到4(代表“完成”)。

每次readyState变化时,readystatechange事件就触发,由onreadystatechange属性指定的事件处理函数就被调用。

在清单3中已经看到了如何调用getReadyStateHandler()函数创建事件处理函数。

然后把这个事件处理函数分配给onreadystatechange属性。

getReadyStateHandler()利用了这样一个事实:

函数是JavaScript中的一级对象。

这意味着函数可以是其他函数的参数,也可以创建和返回其他函数。

getReadyStateHandler()的工作是返回一个函数,检查XMLHttpRequest是否已经完成,并把XML响应传递给调用者指定的事件处理函数。

清单6是getReadyStateHandler()的代码。

清单6.getReadyStateHandler()函数

/*

*ReturnsafunctionthatwaitsforthespecifiedXMLHttpRequest

*tocomplete,thenpassesitsXMLresponsetothegivenhandlerfunction.

*req-TheXMLHttpRequestwhosestateischanging

*responseXmlHandler-FunctiontopasstheXMLresponseto

*/

functiongetReadyStateHandler(req,responseXmlHandler){

//Returnananonymousfunctionthatlistenstothe

//XMLHttpRequestinstance

returnfunction(){

//Iftherequest'sstatusis"complete"

if(req.readyState==4){

//Checkthatasuccessfulserverresponsewasreceived

if(req.status==200){

//PasstheXMLpayloadoftheresponsetothe

//handlerfunction

responseXmlHandler(req.responseXML);

}else{

//AnHTTPproblemhasoccurred

alert("HTTPerror:

"+req.status);

}

}

}

}

HTTP状态码

在清单6中,检查XMLHttpRequest的status属性以查看请求是否成功完成。

status包含服务器响应的HTTP状态码。

在执行简单的GET和POST请求时,可以假设任何大于200(OK)的码都是错误。

如果服务器发送重定向响应(例如301或302),浏览器会透明地进行重定向并从新的位置获取资源;XMLHttpRequest看不到重定向状态码。

而且,浏览器会自动添加Cache-Control:

no-cache头到所有XMLHttpRequest,这样客户代码永远也不用处理304(未经修改)服务器响应。

关于getReadyStateHandler()

getReadyStateHandler()是段相对复杂的代码,特别是如果您不习惯阅读JavaScript的话。

但是通过把这个函数放在JavaScript库中,就可以处理Ajax服务器响应,而不必处理XMLHttpRequest的内部细节。

重要的是要理解如何在自己的代码中使用getReadyStateHandler()。

在清单3中看到了getReadyStateHandler()像这样被调用:

handlerFunction=getReadyStateHandler(req,updateCart)。

在这个示例中,getReadyStateHandler()返回的函数将检查在req变量中的XMLHttpRequest是否已经完成,然后用响应的XML调用名为updateCart的函数。

提取购物车数据

清单7是updateCart()本身的代码。

函数用DOM调用检查购物车的XML文档,然后更新Web页面(请参阅清单1),反映新的购物车内容。

这里的重点是用来从XMLDOM提取数据的调用。

cart元素的generated属性是在Cart序列化为XML时生成的一个时间戳,检查它可以保证新的购物车数据不会被旧的数据覆盖。

Ajax请求天生是异步的,所以这个检查可以处理服务器响应未按次序到达的情况。

清单7.更新页面,反映购物车的XML文档

functionupdateCart(cartXML){

//Gettheroot"cart"elementfromthedocument

varcart=cartXML.getElementsByTagName("cart")[0];

//Checkthatamorerecentcartdocumenthasn'tbeenprocessed

//already

vargenerated=cart.getAttribute("generated");

if(generated>lastCartUpdate){

lastCartUpdate=generated;

//CleartheHTMLlistusedtodisplaythecartcontents

varcontents=document.getElementById("cart-contents");

contents.innerHTML="";

//Loopovertheitemsinthecart

varitems=cart.getElementsByTagName("item");

for(varI=0;I

varitem=items[I];

//Extractthetextnodesfromthenameandquantityelements

varname=item.getElementsByTagNa

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2