|
从XML到Java的数据绑定系列之一:无处不在的对象广告 从XML到Java的数据绑定系列之一:无处不在的对象 Brett McLaughlin 在这个由四部分组成的系列文章的第一部分,我们将弄清什么是数据绑定,与在 Java 应用程序中处理 XML 数据的其它方法相比它有什么优势,以及如何开始使用它。这一部分将考查为什么使用数据绑定,以及如何为各种约束建立模型,使 XML 文档能转换成 Java 对象。同时还涵盖用于生成数据绑定类的输入和输出。 您希望在您的 Java 应用程序中使用 XML 吗?那么好,同成千上万的其他人一起上这条船吧。当您深入了解 XML 以后,也许您会发现 DOM 和 SAX API(请参阅参考资料)不过是唬人的东西。您可能认为肯定存在某种简单方法可以取得 XML 文档,并通过 Java 应用程序访问它,对吗? 不必通过回调或复杂的树状结构,而是使用像 setOwner(Stringowner) 和 int getNumOrders() 这样的方法,对吗?如果您曾经沿着这一思路考虑问题,那么数据绑定就是您要寻找的解决方案。 分析各种选择 应该这样来看待这一问题:选择范围小使您更易于选出适合于您的方法。 回调 树 用于 XML 文档树状表示的最流行的 API 就是 W3C 的推荐标准,即文档对象模型 (DOM)。一种更新的 API,JDOM (这不是首字母缩写词)最近也正一直在推广并流行开来。 (虽然这个方案是我和 Jason Hunter 建立的,但我还得说实话。)另外,DOM 和 JDOM 都是 Spinnaker 方案设计的基本要求,Spinnaker 是一种新的 XML 分析器,它作为 Apache XML 方案的一部分正在开发之中。 虽然树状 API 看起来比事件驱动的 SAX 更易于使用,但它们并不总是合适的。非常大的文档可能需要大量的内存(尤其是使用 DOM 时);当对树结构执行转换 (XSLT) 时,系统可能停止运转甚至彻底崩溃。 虽然更新的 API(如 JDOM)能处理这些问题,但如果您必须处理极大量的数据,它们仍将是一个问题。并且,有时开发人员宁愿将 XML 文档中的数据建模为一个简单的带有值的读写方法的 Java 对象,而不用树状模型工作。例如,开发人员会宁愿不去访问名为 skuNumber 的子节点并设置该节点的文本值,而只想调用 setSkuNumber("mySKU") 并继续进行。 术语解释 JSR-031。 Sun 仍在开发中的一种新的 Java 规范请求,设计用于将 XML 文档编译成一个或多个 Java 类,而在 Java 应用程序中可以方便地使用这些 Java 类。 打包。将 Java 对象转换为 XML 表示,拥有当前值。 解包。根据 XML 对象创建 Java 对象,通常是根据打包生成一个 Java
对象。 这种访问方式正在得到普及,并且当在 XML 文档中存储配置信息时特别有用。许多开发人员发现,它非常便于直接访问所需的参数,而无须使用更复杂的树状结构。虽然这种访问对于文档转换或消息传送没有什么用处,但它对于简单数据处理是极其方便的。它是我们在本文及本系列文章中关注的第三种使用 XML 的方法。 (当然,任何方法随后都会引出一系列新的术语,所以请查看术语解释以了解这些新的行话。) 是否任何 XML 文档都可以转换为 Java 对象?还是仅有某些类型的 XML 文档才可以? 问得好!您很可能只希望将满足一组约束条件的文档转换为 Java 对象。这与定义 Java 接口的方法类似:您确保只实例化和使用适应该接口的对象,允许就如何操作该对象作出假定。同样,您只允许将满足一组约束条件的 XML 对象转换成 Java 对象;这使您能够按希望的方式来使用所创建的对象。 约束数据 那是一大堆问题,但您将在这里找到全部答案。将这些问题看作一系列决策点,一系列选择。首先,您必须确定您能否从该 XML 文档创建 Java 对象(如前面所讨论的那样)。如果能,您就要决定转换应该以新 Java 类的形式出现,还是仅以现有类的一个实例的形式出现。最后,如果选择了现有类,那么使用哪个类呢?结果就是各种各样的决策树。 如果我们考察清单 1 中所示的一个示例 XML 文档,然后再来处理这些问题,则决策树的意义就更加清楚了。此示例文档表示 Enhydra Application Server 中某个服务(具体说就是一个 web 容器)的配置。 清单 1. 一个用于配置 Enhydra 中的 web 容器的 XML 文档
此配置文档包含有关服务本身的版本和名称的信息,以及几个嵌套的项目,每个项目都表示有关该 web 容器服务的一些附加信息。它给出了有关端口的详细信息(包括端口号、协议和安全性),也给出了文档服务信息(包括文档根、用于索引页的默认扩展名以及错误页)。所有这些合在一起,就是配置一个新的 web 容器服务所需的全部信息。 记住这个示例,您就可以开始回答数据表示的各个问题了。 是否适合转换? 转换成类还是实例? 不用这个可能引起混乱的方法,您可以采用一组 XML 约束条件(由一个 DTD 或 XML 方案表示,将在下面讲述),并根据这些约束条件来生成一个 Java 类(或多个类,根据需要)。这个生成的类将表示符合这些约束条件的任何 XML 文档;这些 XML 文档中的每一个都将被解包到生成的类的一个实例中。在这种情况下,就可以为表示 web 服务配置的文档定义约束条件。 这些约束条件将被映射为一个 Java 类,我们将称之为 WebServiceConfiguration。 然后您就可以获得任何一种表示特定 web 服务配置的 XML 文档,并假定此文档符合我们的约束条件,由它而创建出前面生成的类的一个实例。这将允许应用程序将不同的 XML 文档用作相同类型的对象,只要这些文档中的数据对于该对象设计时要达到目的来说是有效的即可。 新类还是现有的类? 利用文档约束条件 最好的情况是,在实际的解包过程开始之前,文档的作者能够保证,配置文档对于他们选择用来表示数据的类是“合法的”。阅读到这一方案的 XML 人士说不定就会转动他们的眼睛并嘀咕说,“好吧,当然您将使用 XML 文档约束条件。”确认数据对选定类的合法性可以通过引用 DTD (文档类型定义)或 XML 方案来完成。 通过使用一组用外部 DTD 或方案文件表示的约束条件,文档作者就可以在这些数据的“接口”上测试配置数据。换句话说,您可以这样来建立应用程序,使之能够对照所需的数据来检查包含在 XML 实例文档中的数据,而所需数据则是在文档约束条件的外部文件中指定的。 这样,您就可以为数据创建一个接口。 在使用 DTD 方案还是使用 XML 方案之间作出决策是一种相当简单的选择:因为 Java 语言是高度类型化的,所以我们希望能在 XML 文档中支持类型化。例如,数据接口应该能够验证,为 web 容器的端口号提供的是整数,而不是字符串,后者在服务启动时将引起错误。DTD 不支持类型检查,所以我们无疑应该选择 XML 方案。虽然 XML 方案在规范的领域在有一点不确定性,但它在很大程度上已趋于稳定,并可望在年内定型。我们可以在一个 XML 方案中编写数据约束条件,然后用这个方案验证可能的实例文档,以确保解包能在这些实例文档上进行。下面的 XML 方案表示我们的 web 容器服务的数据接口。 清单 2. 表示一个 web 容器配置文档的数据接口的 XML 方案
清单 2 中的 XML 方案定义了几个不同的数据对象,它们合起来表示一个 web 服务的配置对象。首先,定义了一个核心服务配置(serviceConfiguration),它包含版本和名称。这可用作所有服务(如负载均衡服务、EJB 容器,当然还有我们的 web 服务)的基本对象。然后,作为此基本服务的扩展,又定义了 web 服务配置(webServiceConfiguration)。请注意,Java 成型之后,方案就已经为数据接口建立了模型。我们将附加的 web 服务属性 port 和 document 添加到 version 和 name 基本属性中。这些属性本身都是对象,具有它们自己的属性(protocol、root、error 等)。 在此方案的定义方式中,特征代表简单的 Java 类型,通常是原始 (primitive) 类型。这样,name 和 version 就分别成为类型 String 和 float 的 Java 原始类型。port 和 document 这样的元素成为 Java 对象,它们可以有自己的属性,还是用特征来表示。 这样就出现了递归现象:元素变成新对象,并对它的每个属性进行检查。如果属性是一个特征,就为此对象创建一个简单的 Java 原始成员变量;如果属性是元素,则创建一个新的对象,并作为一个成员变量将其添加,然后在这个新对象上又开始同样的过程,直到全部类都已创建为止。 从萝卜 ... 嗯 ... XML 获得 Java 清单 3. 为 ServiceConfiguration 接口而从 XML 方案生成的 Java 代码 public interface ServiceConfiguration { 这是相当明白易懂的;清单 3 中的接口为 XML 方案中定义的属性提供读方法和写方法。另外,您将需要生成一个实现类来定义此接口的各个成员变量,并实现此接口中的每个方法。这种使接口从实现中分离出来的方法使我们能够为特定的需要提中供多种实现。 例如,某个特定的服务可能需要执行计算,而不只是接受从写方法中收到的值。 现在考虑那种更复杂的情况还有点为时尚早,但我将在后续文章中重新提到它。然而,一般说来,您仍可以确定实现类应该像什么样子,如清单 4 所示。 清单 4. 为 ServiceConfiguration 实现而从 XML 方案生成的 Java 代码 public class ServiceConfigurationImpl implements
ServiceConfiguration { public void setVersion(float version)
{ public float getVersion() { public void setName(String name) { public String getName() { 相同的原则也适用于 XML 方案中定义的其它对象。您可以在下面查看到其它 Java 类(因为它们都是应该生成的): PortType.java 总结 此系列文章的下一篇将继续考察数据绑定的过程。您将有机会去检查 org.enhydra.xml.binding.SchemaMapper 类,它将接受这第一部分中创建的 XML 方案作为数据接口,并从它创建出一个 Java 接口和实现类。本系列文章的第二部分将详细说明这一过程的每个步骤,并说明如何确保方案被准确表示,以便 XML 文档能接着被转换为生成的类的实例。 梳理一下您学到的 XML 方案和 JDOM (我将在示例代码中使用它们),下个月再见! 下载包含本文中的示例代码的 zip 文件,包括所有 Java 类 和 XML 文件。 从 David Megginson 的 SAX 页下载 The Simple API for XML (SAX) 的 2000 年 5 月版,这是一个基于事件的 API,用于在 Java 应用程序中读取 XML。 从 W3C DOM 工作小组的正式网页上不断了解 DOM 的最新状态,DOM 即文档对象模型 (DOM),该模型是一种基于树的 API,用于在 Java 应用程序中读写 XML。 下载 JDOM,这是一种使 XML 在 Java 应用程序中的使用更加简单和直观的 API,并了解有关 JDOM 方案的内容。 研读 JSR-031:数据绑定,这是 Sun 的数据绑定规范要求。 下载 Enhydra,一种开放源代码的 Java 应用程序服务器。 从 W3C 的网站阅读由两部分组成的 XML 方案规范(目前为工作初稿)的最新细节:结构和数据类型。 Brett McLaughlin 有能力写一本关于 Java 应用程序和 XML 这一主题的书 -- 他也这样做了:订购《Java and XML》,由 O'Reilly 出版。 需要关于 XML 更基本的导论吗?试一试 developerWorks 的 XML 导论教程和其它教学性内容,其中包括了大多数基本主题。 作者简介 如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐 jill.jiang@amteam.org | 021-51096826-112 | 在线联系 |
节能与优化IT 企业CIO过冬良策当前金融危机的影响还在继续漫延,很多企业都在苦寻过冬的良策,在这种情况下,节能与优化技术与产品无疑成为CIO们关注的首要对象,本次选题就是针对节能与优化IT来为CIO们提供过冬的良…… |
|
|