




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、面向Java 开发人员的 Ajax:构建动态的 Java 应用程序Ajax 为更好的 Web 应用程序铺平了道路文档选项打印本页将此页作为电子邮件发送讨论样例代码级别: 中级Philip McCarthy(), 软件开发顾问, 独立咨询顾问2005 年 10 月 20 日在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java 开发人员来说也是一个严峻的挑战。在这个系列中,作者 Philip McCarthy 介绍了一种创建动态应用程序体验的开创性方式。Ajax(异步 JavaScript 和 XML)是一种编程技术,它允许为基于
2、Java 的 Web 应用程序把 Java 技术、XML 和 JavaScript 组合起来,从而打破页面重载的范式。Ajax(即异步 JavaScript 和 XML)是一种 Web 应用程序开发的手段,它采用客户端脚本与 Web 服务器交换数据。所以,不必采用会中断交互的完整页面刷新,就可以动态地更新 Web 页面。使用 Ajax,可以创建更加丰富、更加动态的 Web 应用程序用户界面,其即时性与可用性甚至能够接近本机桌面应用程序。Ajax 不是一项技术,而更像是一个模式 一种识别和描述有用的设计技术的方式。Ajax 是新颖的,因为许多开发人员才刚刚开始知道它,但是所有实现 Ajax 应用
3、程序的组件都已经存在若干年了。它目前受到重视是因为在 2004 和 2005 年出现了一些基于 Ajax 技术的非常棒的动态 Web UI,最著名的就是 Google 的 GMail 和 Maps 应用程序,以及照片共享站点 Flickr。这些用户界面具有足够的开创性,有些开发人员称之为“Web 2.0”,因此对 Ajax 应用程序的兴趣飞速上升。在这个系列中,我将提供使用 Ajax 开发应用程序需要的全部工具 。在第一篇文章中,我将解释 Ajax 背后的概念,演示为基于 Java 的 Web 应用程序创建 Ajax 界面的基本步骤。我将使用代码示例演示让 Ajax 应用程序如此动态的服务器端
4、 Java 代码和客户端 JavaScript。最后,我将指出 Ajax 方式的一些不足,以及在创建 Ajax 应用程序时应当考虑的一些更广的可用性和访问性问题。更好的购物车可以用 Ajax 增强传统的 Web 应用程序,通过消除页面装入从而简化交互。为了演示这一点,我采用一个简单的购物车示例,在向里面添加项目时,它会动态更新。这项技术如果整合到在线商店,那么用户可以持续地浏览和向购物车中添加项目,而不必在每次点击之后都等候完整的页面更新。虽然这篇文章中的有些代码特定于购物车示例,但是演示的技术可以应用于任何 Ajax 应用程序。清单 1 显示了购物车示例使用的有关 HTML 代码,整篇文章中
5、都会使用这个 HTML。清单1. 购物车示例的有关片断Name Description Price . Hat Stylish bowler hat $19.99 Add to Cart . Total cost: $0.00回页首Ajax 往返过程Ajax 交互开始于叫作XMLHttpRequest的 JavaScript 对象。顾名思义,它允许客户端脚本执行 HTTP 请求,并解析 XML 服务器响应。Ajax 往返过程的第一步是创建XMLHttpRequest的实例。在XMLHttpRequest对象上设置请求使用的 HTTP 方法(GET或POST)以及目标 URL。现在,您还记得 A
6、jax 的第一个a是代表异步(asynchronous)吗?在发送 HTTP 请求时,不想让浏览器挂着等候服务器响应。相反,您想让浏览器继续对用户与页面的交互进行响应,并在服务器响应到达时再进行处理。为了实现这个要求,可以在XMLHttpRequest上注册一个回调函数,然后异步地分派XMLHttpRequest。然后控制就会返回浏览器,当服务器响应到达时,会调用回调函数。在 Java Web 服务器上,请求同其他HttpServletRequest一样到达。在解析了请求参数之后,servlet 调用必要的应用程序逻辑,把响应序列化成 XML,并把 XML 写入HttpServletRespo
7、nse。回到客户端时,现在调用注册在XMLHttpRequest上的回调函数,处理服务器返回的 XML 文档。最后,根据服务器返回的数据,用 JavaScript 操纵页面的 HTML DOM,把用户界面更新。图 1 是 Ajax 往返过程的顺序图。图 1. Ajax 往返过程现在您对 Ajax 往返过程有了一个高层面的认识。下面我将放大其中的每一步骤,进行更详细的观察。如果过程中迷了路,请回头看图 1 由于 Ajax 方式的异步性质,所以顺序并非十分简单。回页首分派 XMLHttpRequest我将从 Ajax 序列的起点开始:创建和分派来自浏览器的XMLHttpRequest。不幸的是,不
8、同的浏览器创建XMLHttpRequest的方法各不相同。清单 2 的 JavaScript 函数消除了这些依赖于浏览器的技巧,它可以检测当前浏览器要使用的正确方式,并返回一个可以使用的XMLHttpRequest。最好是把它当作辅助代码:只要把它拷贝到 JavaScript 库,并在需要XMLHttpRequest的时候使用它就可以了。清单 2. 创建跨浏览器的 XMLHttpRequest/* * Returns a new XMLHttpRequest object, or false if this browser * doesnt support it */function newX
9、MLHttpRequest() var xmlreq = false; if (window.XMLHttpRequest) / Create XMLHttpRequest object in non-Microsoft browsers xmlreq = new XMLHttpRequest(); else if (window.ActiveXObject) / Create XMLHttpRequest via MS ActiveX try / Try to create XMLHttpRequest in later versions / of Internet Explorer xml
10、req = new ActiveXObject(Msxml2.XMLHTTP); catch (e1) / Failed to create required ActiveXObject try / Try version supported by older versions / of Internet Explorer xmlreq = new ActiveXObject(Microsoft.XMLHTTP); catch (e2) / Unable to create an XMLHttpRequest with ActiveX return xmlreq; 稍后我将讨论处理那些不支持X
11、MLHttpRequest的浏览器的技术。目前,示例假设清单 2 的newXMLHttpRequest函数总能返回XMLHttpRequest实例。返回示例的购物车场景,我想要当用户在目录项目上点击 Add to Cart 时启动 Ajax 交互。名为addToCart()的onclick处理函数负责通过 Ajax 调用来更新购物车的状态(请参阅清单 1)。正如清单 3 所示,addToCart()需要做的第一件事是通过调用清单 2 的newXMLHttpRequest()函数得到XMLHttpRequest对象。接下来,它注册一个回调函数,用来接收服务器响应(我稍后再详细解释这一步;请参阅清
12、单 6)。因为请求会修改服务器上的状态,所以我将用 HTTPPOST做这个工作。通过POST发送数据要求三个步骤。第一,需要打开与要通信的服务器资源的POST连接 在这个示例中,服务器资源是一个映射到 URLcart.do的 servlet。然后,我在XMLHttpRequest上设置一个头,指明请求的内容是表单 编码的数据。最后,我用表单编码的数据作为请求体发送请求。清单 3 把这些步骤放在了一起。清单 3. 分派 Add to Cart XMLHttpRequest/* * Adds an item, identified by its product code, to the shopp
13、ing cart * itemCode - product code of the item to add. */function addToCart(itemCode) / Obtain an XMLHttpRequest instance var req = newXMLHttpRequest(); / Set the handler function to receive callback notifications / from the request object var handlerFunction = getReadyStateHandler(req, updateCart);
14、 req.onreadystatechange = handlerFunction; / Open an HTTP POST connection to the shopping cart servlet. / Third parameter specifies request is asynchronous. req.open(POST, cart.do, true); / Specify that the body of the request contains form data req.setRequestHeader(Content-Type, application/x-www-f
15、orm-urlencoded); / Send form encoded data stating that I want to add the / specified item to the cart. req.send(action=add&item=+itemCode);这就是建立 Ajax 往返过程的第一部分,即创建和分派来自客户机的 HTTP 请求。接下来是用来处理请求的 Java servlet 代码。回页首servlet 请求处理用 servlet 处理XMLHttpRequest,与处理普通的浏览器 HTTP 请求一样。可以用HttpServletRequest.getPara
16、meter()得到在 POST 请求体中发送的表单编码数据。Ajax 请求被放进与来自应用程序的常规 Web 请求一样的HttpSession中。对于示例购物车场景来说,这很有用,因为这让我可以把购物车状态封装在 JavaBean 中,并在请求之间在会话中维持这个状态。清单 4 是处理 Ajax 请求、更新购物车的简单 servlet 的一部分。Cartbean 是从用户会话中获得的,并根据请求参数更新它的状态。然后Cart被序列化成 XML,XML 又被写入ServletResponse。重要的是把响应的内容类型设置为application/xml,否则XMLHttpRequest不会把响应
17、内容解析成 XML DOM。清单 4. 处理 Ajax 请求的 servlet 代码public void doPost(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException Cart cart = getCartFromSession(req); String action = req.getParameter(action); String item = req.getParameter(item); if (action != null)&(item != null) / Add or re
18、move items from the Cart if (add.equals(action) cart.addItem(item); else if (remove.equals(action) cart.removeItems(item); / Serialize the Carts state to XML String cartXml = cart.toXml(); / Write XML to response. res.setContentType(application/xml); res.getWriter().write(cartXml);清单 5 显示了Cart.toXml
19、()方法生成的示例 XML。它很简单。请注意cart元素的generated属性,它是System.currentTimeMillis()生成的一个时间戳。清单 5. Cart 对象的XML 序列化示例 Hat 2 Chair 1 Dog 1 如果查看应用程序源代码(可以从下载一节得到)中的 Cart.java,可以看到生成 XML 的方式只是把字符串添加在一起。虽然对这个示例来说足够了,但是对于从 Java 代码生成 XML 来说则是最差的方式。我将在这个系列的下一期中介绍一些更好的方式。现在您已经知道了CartServlet响应XMLHttpRequest的方式。下一件事就是返回客户端,查
20、看如何用 XML 响应更新页面状态。回页首用 JavaScript 进行响应处理XMLHttpRequest的readyState属性是一个数值,它指出请求生命周期的状态。它从 0(代表“未初始化”)变化到 4(代表“完成”)。每次readyState变化时,readystatechange事件就触发,由onreadystatechange属性指定的事件处理函数就被调用。在清单 3中已经看到了如何调用getReadyStateHandler()函数创建事件处理函数。然后把这个事件处理函数分配给onreadystatechange属性。getReadyStateHandler()利用了这样一个事
21、实:函数是 JavaScript 中的一级对象。这意味着函数可以是其他函数的参数,也可以创建和返回其他函数。getReadyStateHandler()的工作是返回一个函数,检查XMLHttpRequest是否已经完成,并把 XML 响应传递给调用者指定的事件处理函数。清单 6 是getReadyStateHandler()的代码。清单 6. getReadyStateHandler() 函数/* * Returns a function that waits for the specified XMLHttpRequest * to complete, then passes its XML
22、 response to the given handler function. * req - The XMLHttpRequest whose state is changing * responseXmlHandler - Function to pass the XML response to */function getReadyStateHandler(req, responseXmlHandler) / Return an anonymous function that listens to the / XMLHttpRequest instance return functio
23、n () / If the requests status is complete if (req.readyState = 4) / Check that a successful server response was received if (req.status = 200) / Pass the XML payload of the response to the / handler function responseXmlHandler(req.responseXML); else / An HTTP problem has occurred alert(HTTP error: +
24、req.status); HTTP 状态码在清单 6 中,检查XMLHttpRequest的status属性以查看请求是否成功完成。status包含服务器响应的 HTTP 状态码。在执行简单的GET和POST请求时,可以假设任何大于 200 (OK)的码都是错误。如果服务器发送重定向响应(例如 301 或 302),浏览器会透明地进行重定向并从新的位置获取资源;XMLHttpRequest看不到重定向状态码。而且,浏览器会自动添加Cache-Control: no-cache头到所有XMLHttpRequest,这样客户代码永远也不用处理 304(未经修改)服务器响应。关于 getReadyS
25、tateHandler()getReadyStateHandler()是段相对复杂的代码,特别是如果您不习惯阅读 JavaScript 的话。但是通过把这个函数放在 JavaScript 库中,就可以处理 Ajax 服务器响应,而不必处理XMLHttpRequest的内部细节。重要的是要理解如何在自己的代码中使用getReadyStateHandler()。在清单 3中看到了getReadyStateHandler()像这样被调用:handlerFunction = getReadyStateHandler(req, updateCart)。在这个示例中,getReadyStateHandle
26、r()返回的函数将检查在req变量中的XMLHttpRequest是否已经完成,然后用响应的 XML 调用名为updateCart的函数。提取购物车数据清单 7 是updateCart()本身的代码。函数用 DOM 调用检查购物车的 XML 文档,然后更新 Web 页面(请参阅清单 1),反映新的购物车内容。这里的重点是用来从 XML DOM 提取数据的调用。cart元素的generated属性是在Cart序列化为 XML 时生成的一个时间戳,检查它可以保证新的购物车数据不会被旧的数据覆盖。Ajax 请求天生是异步的,所以这个检查可以处理服务器响应未按次序到达的情况。清单 7. 更新页面,反映
27、购物车的 XML 文档function updateCart(cartXML) / Get the root cart element from the document var cart = cartXML.getElementsByTagName(cart)0; / Check that a more recent cart document hasnt been processed / already var generated = cart.getAttribute(generated); if (generated lastCartUpdate) lastCartUpdate = g
28、enerated; / Clear the HTML list used to display the cart contents var contents = document.getElementById(cart-contents); contents.innerHTML = ; / Loop over the items in the cart var items = cart.getElementsByTagName(item); for (var I = 0 ; I items.length ; I+) var item = itemsI; / Extract the text n
29、odes from the name and quantity elements var name = item.getElementsByTagName(name)0 .firstChild.nodeValue; var quantity = item.getElementsByTagName(quantity)0 .firstChild.nodeValue; / Create and add a list item HTML element for this cart item var li = document.createElement(li); li.appendChild(docu
30、ment.createTextNode(name+ x +quantity); contents.appendChild(li); / Update the carts total using the value from the cart document document.getElementById(total).innerHTML = cart.getAttribute(total);到此,整个 Ajax 往返过程完成了,但是您可能想让 Web 应用程序运行一下查看实际效果(请参阅下载一节)。这个示例非常简单,有很多需要改进之处。例如,我包含了从购物车中清除项目的服务器端代码,但是无法
31、从 UI 访问它。作为一个好的练习,请试着在应用程序现有的 JavaScript 代码之上构建出能够实现这个功能的代码。回页首使用 Ajax 的挑战就像任何技术一样,使用 Ajax 也有许多出错的可能性。我目前在这里讨论的问题还缺乏容易的解决方案,但是会随着 Ajax 的成熟而改进。随着开发人员社区增加开发 Ajax 应用程序的经验,将会记录下最佳实践和指南。XMLHttpRequest 的可用性Ajax 开发人员面临的一个最大问题是:在没有XMLHttpRequest可用时该如何响应?虽然主要的现代浏览器都支持XMLHttpRequest,但仍然有少数用户的浏览器不支持,或者浏览器的安全设置
32、阻止使用XMLHttpRequest。如果开发的 Web 应用程序要部署在企业内部网,那么可能拥有指定支持哪种浏览器的权力,从而可以认为XMLHttpRequest总能使用。但是,如果要部署在公共 Web 上,那么就必须当心,如果假设XMLHttpRequest可用,那么就可能会阻止那些使用旧的浏览器、残疾人专用浏览器和手持设备上的轻量级浏览器的用户使用您的应用程序。所以,您应当努力让应用程序“平稳降级”,在没有XMLHttpRequest支持的浏览器中也能够工作。在购物车的示例中,把应用程序降级的最好方式可能是让 Add to Cart 按钮执行一个常规的表单提交,刷新页面来反映购物车更新后
33、的状态。Ajax 的行为应当在页面装入的时候就通过 JavaScript 添加到页面,只有在XMLHttpRequest可用时才把 JavaScript 事件处理函数附加到每个 Add to Cart 按钮。另一种方式是在用户登录时检测XMLHttpRequest是否可用,然后相应地提供应用程序的 Ajax 版本或基于表单的普通版本。可用性考虑关于 Ajax 应用程序的某些可用性问题比较普遍。例如,让用户知道他们的输入已经注册了可能是重要的,因为沙漏光标和 spinning 浏览器的常用反馈机制“throbber”对XMLHttpRequest不适用。一种技术是用“Now updating.”
34、类型的信息替换 Submit 按钮,这样用户在等候响应期间就不会反复单击按钮了。另一个问题是,用户可能没有注意到他们正在查看的页面的某一部分已经更新了。可以使用不同的可视技术,把用户的眼球带到页面的更新区域,从而缓解这个问题。由 Ajax 更新页面造成的其他问题还包括:“破坏了”浏览器的后退按钮,地址栏中的 URL 也无法反映页面的整个状态,妨碍了设置书签。请参阅参考资料一节,获得专门解决 Ajax 应用程序可用性问题的文章。服务器负载用 Ajax 实现代替普通的基于表单的 UI,会大大提高对服务器发出的请求数量。例如,一个普通的 Google Web 搜索对服务器只有一个请求,是在用户提交搜
35、索表单时出现的。而 Google Suggest 试图自动完成搜索术语,它要在用户输入时向服务器发送多个请求。在开发 Ajax 应用程序时,要注意将要发送给服务器的请求数量以及由此造成的服务器负荷。降低服务器负载的办法是,在客户机上对请求进行缓冲并且缓存服务器响应(如果可能的话)。还应该尝试将 Ajax Web 应用程序设计为在客户机上执行尽可能多的逻辑,而不必联络服务器。处理异步非常重要的是,要理解无法保证XMLHttpRequest会按照分派它们的顺序完成。实际上,应当假设它们不会按顺序完成,并且在设计应用程序时把这一点记在心上。在购物车的示例中,使用最后更新的时间戳来确保新的购物车数据不
36、会被旧的数据覆盖(请参阅清单 7)。这个非常基本的方式可以用于购物车场景,但是可能不适合其他场景。所以在设计时请考虑如何处理异步的服务器响应。回页首结束语现在您对 Ajax 的基本原则应当有了很好的理解,对参与 Ajax 交互的客户端和服务器端组件也应当有了初步的知识。这些是基于 Java 的 Ajax Web 应用程序的构造块。另外,您应当理解了伴随 Ajax 方式的一些高级设计问题。创建成功的 Ajax 应用程序要求整体考虑,从 UI 设计到 JavaScript 设计,再到服务器端架构;但是您现在应当已经武装了考虑其他这些方面所需要的核心 Ajax 知识。如果使用这里演示的技术编写大型
37、Ajax 应用程序的复杂性让您觉得恐慌,那么有好消息给您。由于 Struts、Spring 和 Hibernate 这类框架的发展把 Web 应用程序开发从底层 Servlet API 和 JDBC 的细节中抽象出来,所以正在出现简化 Ajax 开发的工具包。其中有些只侧重于客户端,提供了向页面添加可视效果的简便方式,或者简化了对XMLHttpRequest的使用。有些则走得更远,提供了从服务器端代码自动生成 Ajax 接口的方式。这些框架替您完成了繁重的任务,所以您可以采用更高级的方式进行 Ajax 开发。我在这个系列中将研究其中的一些。Ajax 社区正在快速前进,所以会有大量有价值的信息涌
38、现。在阅读这个系列的下一期之前,我建议您参考参考资料一节中列出的文章,特别是如果您是刚接触 Ajax 或客户端开发的话。您还应当花些时间研究示例源代码并考虑一些增强它的方式。在这个系列的下一篇文章中,我将深入讨论XMLHttpRequestAPI,并推荐一些从 JavaBean 方便地创建 XML 的方式。我还将介绍替代 XML 进行 Ajax 数据传递的方式,例如 JSON(JavaScript Object Notation)轻量级数据交换格式。回页首下载描述名字大小下载方法Sample codej-ajax1.zip8 KBHTTP关于下载方法的信息参考资料学习 您可以参阅本文在 dev
39、eloperWorks 全球站点上的英文原文。 “Beyond the DOM”(Dethe Elza, developerWorks,2005 年 5 月):进行 XML 文档访问的有用的 JavaScript 技术。 “AJAX 及使用 E4X 编写 Web 服务脚本,第 1 部分”(Paul Fremantle 和 Anthony Elder,developerWorks,2005 年 4 月):用 Ajax 在支持 E4X JavaScript 扩展的浏览器中进行 SOAP 调用。 “Ajax: A New Approach to Web Applications”(Jesse Jam
40、es Garrett,Adaptive Path,2005 年 2 月):介绍 Ajax 起源的短文。 The Java BluePrints Solutions Catalog:介绍了 Ajax 在几个常见 Web 应用程序场景中的应用。 AjaxP:包含多项改进 Ajax 应用程序的 UI 技术。 XMLHttpRequest Usability Guidelines:对使用 Ajax 提高用户体验的建议。 Ajax Mistakes:Ajax 应用程序应当避免的可用性问题。 Java 技术专区:在这里可以找到关于 Java 编程的各个方面的文章。获得产品和技术 Mo
41、zilla Firefox:DOM Inspector 和 JavaScript Debugger 扩展消除了许多 Ajax 开发的痛苦。讨论 参与论坛讨论。 developerWorks blogs:加入 developerWorks 社区。面向 Java 开发人员的 Ajax:Ajax 的 Java 对象序列化在 Ajax 应用程序中序列化数据的五种途径级别: 中级Philip McCarthy(), 软件开发顾问, 独立顾问2005 年 10 月 24 日如果您正在使用异步 JavaScript 和 XML(Ajax)进行 Java Web 开发
42、,那么您最关心的问题可能就是把数据从服务器传递给客户机。在面向 Java 开发人员的 Ajax系列的第二篇文章中,Philip McCarthy 介绍了 Java 对象序列化的五种方式,并提供了选择最适合应用程序的数据格式和技术所需要的全部信息。在这个系列的第一篇文章中,我介绍了 Ajax 的构造块: 如何用 JavaScriptXMLHttpRequest对象从 Web 页面向服务器发送异步请求。 如何用 Java servlet 处理和响应请求(向客户机返回 XML 文档)。 如何在客户端用响应文档更新页面视图。这一次,我将继续讨论 Ajax 开发的基础知识,但是将侧重于许多 Java W
43、eb 开发人员最关心的问题:为客户机生成数据。多数 Java 开发人员已经把模型-视图-控制器(MVC)模式应用在他们的 Web 应用程序上。在传统的 Web 应用程序中,视图组件由 JSP 或者其他表示技术(例如 Velocity 模板)构成。这些表示组件动态地生成全新的 HTML 页面,替代用户以前正在查看的页面,从而更新用户界面。但是,在 Java Web 应用程序使用 Ajax UI 的情况下,基于从XMLHttpRequest的响应接收到的数据,JavaScript 客户端代码对于更新用户看到的内容负有最终责任。从服务器的角度来看,视图成为它响应客户机请求而发送的数据表示。这篇文章侧
44、重于可以用来生成 Java 对象以数据为中心的视图的技术。我将演示可以把 JavaBeans 变成 XML 文档的各种方法,并且讨论每种方法的优劣。您将看到为什么 XML 并不总是最好的途径:对于简单的 Ajax 请求来说,传输纯文本更好。最后,我将介绍 JavaScript 对象标注(JSON)。JSON 允许数据以序列化的 JavaScript 对象图的形式传输,在客户端代码中处理序列化的 JavaScript 对象图极为容易。关于示例我将使用一个示例应用程序和几个用例来演示这里讨论的技术特性和技术。图 1 显示的极为简单的数据模型可以表示示例用例。这个模型代表在线商店中的顾客帐户。顾客拥
45、有以前订单的集合,每个订单包含几个商品。图 1. 简单的对象模型虽然XMLHttpRequest对于发送数据使用的格式没有做任何限制,但是对于多数目的来说,只发送传统的表单数据是适合的,所以我的讨论集中在服务器的响应上。响应也可以有基于文本的格式,但是正如它的名字表示的,XMLHttpRequest具有内置的处理 XML 响应数据的能力。这使 XML 成为 Ajax 响应的默认选择,所以我们从 XML 格式开始讨论。从 Java 类产生 XML把 Ajax 响应作为 XML 来传递有许多原因:每个支持 Ajax 的浏览器都有导航 XML 文档的方法,也有许多服务器端技术可以处理 XML 数据。
46、通过制定一个方案,描述要交换的文档类型,在 Ajax 客户端和服务器端之间很容易定义合约,而且如果服务器端架构采用面向服务的方式,那么使用 XML 也可以允许非 Ajax 客户机使用您提供的数据。我将考虑从 Java 对象产生 XML 数据的三种方法,并讨论每种方法的优劣。自行进行序列化首先,可以从对象图以编程的方式生成 XML。这种方式可以简单到只是在每个 JavaBean 类中实现toXml()方法即可。然后就可以选择合适的 XML API,让每个 bean 提供表示自己状态的元素,并递归地对自己的成员调用对象图。显然,这种方式无法扩展到大量的类,因为每个类都需要专门编写自己的 XML 生
47、成代码。从好的方面来看,这是一个实现起来简单的方式,没有额外的配置支出或者更复杂的构建过程支出,任何 JavaBean 图都可以只用几个调用就变成 XML 文档。在本系列前一篇文章的示例代码中,我把 XML 标记字符串连接在一起,实现了toXml()方法。上次我就提到过,这是个糟糕的方法,因为它把确保标记配对、实体编码等工作的负担放在每个toXml()方法的代码中。在 Java 平台上有几个 XML API 可以替您做这些工作,这样您就可以把精力集中在 XML 的内容上。清单 1 用 JDOM API 实现了在线商店示例中表示订单的类中的toXml()(请参阅图 1)。清单 1. Order
48、类的 toXml() 的 JDOM 实现public Element toXml() Element elOrder = new Element(order); elOrder.setAttribute(id,id); elOrder.setAttribute(cost,getFormattedCost(); Element elDate = new Element(date).addContent(date); elOrder.addContent(elDate); Element elItems = new Element(items); for (Iterator iter = item
49、s.iterator() ; iter.hasNext() ; ) elItems.addContent(iter.next().toXml(); elOrder.addContent(elItems); return elOrder;在这里可以看到用 JDOM 创建元素、使用属性和添加元素内容有多么简单。递归地调用复合 JavaBean 的toXml()方法是为了取得它们子图的Element表示。例如,items元素的内容是通过调用Order聚合的每个Item对象上的toXml()得到的。一旦所有的 JavaBean 都实现了toXml()方法,那么把任意对象图序列化成 XML 文档并返回给
50、 Ajax 客户机就简单了,如清单 2 所示。清单 2. 从 JDOM 元素生成 XML 响应public void doGet(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException, ServletException String custId = req.getParameter(username); Customer customer = getCustomer(custId); Element responseElem = customer.toXml(); Document responseDoc = new Document(responseElem); res.setContentType(application/xml); new XMLOutputter().ou
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- ABS合金项目可行性研究报告
- 2025至2030年小型机械式剪板机项目投资价值分析报告
- 《1 双色火》(教学设计)-2023-2024学年四年级下册综合实践活动吉美版
- 2025至2030年中国香辣腊鸡腿数据监测研究报告
- 2025至2030年凹凸扣自封带彩条吹膜机组项目投资价值分析报告
- 2025至2030年低噪声下变频器LNB项目投资价值分析报告
- 2025至2030年CVD试听机项目投资价值分析报告
- 2025至2030年中国抗菌被数据监测研究报告
- 2025至2031年中国EGF营养霜行业投资前景及策略咨询研究报告
- 2025至2030年中国高效脱苯酚萃取剂数据监测研究报告
- 湖南省长沙市2023-2024学年八年级下学期入学考试英语试卷(附答案)
- 青海2024年01月青海省省直机关遴选公务员69人^2024年国家公务员考试考试大纲历年真题笔试历年高频考点难、易错点荟萃附答案带详解
- 一年级美术课后辅导教案-1
- 智慧社区建设中的智能化医疗与康养服务
- 2023-2024年人教版八年级上册数学期末模拟试卷(含答案)
- 数据采集管理制度范文
- 幼儿园小班开学家长会课件
- 中药抗骨质疏松作用
- 中建综合支吊架施工方案
- 建筑施工规范大全
- 幼儿园开学家长会PPT模板(含完整内容)
评论
0/150
提交评论