实用数据绑定: JaxMe——这一领域的新手

来源:百度文库 编辑:神马文学网 时间:2024/05/04 17:37:05
使用 JaxMe 生成类

文档选项

将此页作为电子邮件发送

样例代码
拓展 Tomcat 应用

下载 IBM 开源 J2EE 应用服务器 WAS CE 新版本 V1.1
级别: 初级
Brett McLaughlin (brett@oreilly.com), 编辑, O‘Reilly and Associates
2004 年 7 月 01 日
本 专栏的上一期全面概括了 JAXB,为您学习不同的数据绑定实现作好了准备。本文开始深入考察 JaxMe,它是 JAXB 的一种开放源代码实现。除了对基本 JAXB 规范作了一些改进之外,JaxMe 还集成了数据库和 Enterprise JavaBeans,这是对基本数据绑定行为的重要扩展。您可以通过“XML 和 Java 技术”讨论论坛与作者和其他读者交流您对本文的看法。(您也可以单击本文顶端和底端的 讨论来访问论坛。)
SUN 的 JAXB,即 Java API for XML,曾经受到广泛的批评,这并不是一个秘密。在早期的版本(beta 或者其他某个版本)中,它是基于 DTD 的,完全不支持 W3C XML Schema。这种状态持续了一年多,然后,JAXB 突然发布了 1.0 版。虽然这个版本解决了模式的支持问题,却完全抛弃了 DTD,开发人员编写的代码(当然是对 beta 软件)突然不能使用了。近来,JAXB 得到了一些支持,但它仍然是一个非常封闭的环境,并在实现中留下许多很深的隐患。
本文将介绍的 JaxMe 项目保留了 JAXB 的许多好的特性,并克服了它的很多不足。首先 JaxMe 是源代码开放的(在 Apache 的大伞之下),这意味着即使它现在就消失了,开发人员也仍然能够使用甚至修改它的源代码,从而保证依赖于它的那些代码仍然能够很好地运行。如果说这一点还 不够,JaxMe 还提供了数据库交互、对 Enterprise JavaBeans 的支持等很多好的特性。
为了帮助您使用 JaxMe,我将详细地介绍类生成的方法。虽然这只是一项非常基本的任务,但可以帮助您熟悉 JaxMe,从而可以了解那些更有趣的特性。。
设置 JaxMe 非常轻松。请访问 JaxMe 项目站点(请参阅参考资料链接),并从 Apache 镜像站点下载其二进制形式。在撰写本文的时候,我下载的文件是 incubated-jaxme-0.2-bin.tar.gz。(在发布本文之前刚刚出现了 0.3 版,方法一样,只不过文件名改成了 incubated-jaxme-0.3-bin.tar.gz)。在您的开发机器上对该文件进行解压缩。虽然可以在命令行中使用 JaxME,但是这样做太痛苦了(因为有 太多的JAR 文件),本文使用 Ant 来处理 JaxMe 任务。强烈建议您也这样做,这里包括所有相关的 Ant 文件,而且很容易根据需要进行修改。




回页首
和 Jaxb 一样,在用 JaxMe 做某些工作之前需要一些 XML。清单 1 是一个非常简单的 XML 模式,它定义了一个学生。当然这里的定义很不完善,但是为了把精力集中到 JaxMe 而不是模式的语义上,有必要保持示例的简单性。

如果已经正确地设置了 Ant 构建过程(本文的最后还会详细加以说明),只需输入 ant generate 就可以从这个模式生成类。我将这些细节留在了文章的最后,以便在阅读本文的过程中您能够把精力放在 JaxMe 及其语义上,最后再专门看一看 Ant。实际上,我建议您先通读一遍本文,然后再逐段地测试代码。这样,在您实际输入代码的时候,就已经掌握了其中的概念,可以更快地解决其中遇到的问 题。
所有生成的类都将放在 targetNamespace 属性指定的包中。这种约定是 JaxMe 独有的,因此,您应该好好地理解它的工作原理。看一看作为该属性参数提供的 URI: http://dw.ibm.com/jaxme/student 。这个字符串将被 JaxMe 模式编译器转化成包的名称。首先去掉“http://”,然后 逆转URI 中的主机名部分(这里就是“dw.ibm.com”),得到“com.ibm.dw”。这看起来有点奇怪,但实际上是通常的打包机制,对于用于开发特定站点或者 Bean(特别是标签库的包),这非常合理。
最后,URI 的剩余部分用斜杠( / )分隔,并将它们附加到从主机名派生的包名的后面。因此对于清单 1 中的模式,完整的包就是 com.ibm.dw.jaxme.student 。这个模式生成的所有类都将放在这个包中。
除了为 JaxMe 提供信息之外, targetNamespace 属性对于 XML 还有一些特殊的意义。它告诉模式处理程序将所有创建的构造(如 Address 这样的复杂类型)都放在该名称空间中。这意味着您需要通过这个名称空间引用这些构造,如果名称空间很长,则应该定义一个前缀映射到该名称空间。
注意:如果不能理解上面那一句话,您可能需要在学习一下 XML,特别是如何将 XML Schema 用于 XML。有关的更多信息,请参阅文章后面的参考资料(以及 developerWorks XML 专区的其他文章)。现在不妨继续读下去,请相信我,但是要成为一名 JaxMe 专家,就必须花一些时间完全理解名称空间。
在清单 1 的模式中,引用是通过 stu 前缀实现的。通过这个前缀,您可以很容易定义类型,然后通过模式引用它们(使用名称空间前缀)。
还应该知道,JaxMe 大量使用 include 指令(该例中未使用)。特别是对于大型模式,您可以将这些定义分段放在不同的文件中,然后在最高层的模式中使用下面方式引用它们:

XML 模式处理程序将信息转移给 JaxMe,而对这些文件完全不作区分,因此我们建议,如果需要就使用多个模式。




回页首
生成类之后,花点时间熟悉一下生成的结果。虽然这些类与 JAXB 创建的构造非常类似,但也存在少量细微的差别。
它表示一个 XML 元素(来自清单 1),是类层次的基本结构。实际上,它只是一个简单的接口,扩展了 StudentType (由 JaxMe 生成)和 Element ,后者是 JaxMe 运行时 API 的一部分。当然,这个类(以及所有其他生成的类)都在 com.ibm.dw.jaxme.student 包中。
JaxMe 中任何名为 XXXType (其中 XXX 是像“Student”或“Address”这样的名称)的对象都是从模式中派生的定义。清单 2 显示了这个类的源代码,其中的内容非常简单。
package com.ibm.dw.jaxme.student; public interface StudentType { public String getFirstName(); public void setFirstName(String pFirstName); public String getLastName(); public void setLastName(String pLastName); public AddressType getAddress(); public void setAddress(AddressType pAddress); }
所有的属性都有访问( getXXX() )和修改( setXXX() )方法。当然,无论是简单字符串类型和更加复杂的类型,如 Address ,这些类型都用类表示,后面带有“Type”,因此在生成的清单中会看到对 AddressType 的引用。
现在您已经看到了清单 2和 StudentType.java,这些代码非常简单,您可以自行加以分析。
该文件在很多方面是 JaxMe 和特定于域的类之间的桥梁,最重要的方法有:
newInstance() 在特定于域的上下文中创建一个新元素并返回它。
createStudentType() 新创建的顶级 Student 元素。
非常奇怪的是,任何 JaxMe 文档中都没有提到该文件,提供的示例中也没有使用它。我个人倒是发现了它的某些用处,但是不建议您依赖该文件。不需要它也能完成所有的工作,如果有意在文档中忽略它,那么很可能在将来的版本中该文件就不会再出现。
该 XML 文件处理从 XML 到 Java 代码(或者相反)的映射。它将元素和类、字段和属性等联系起来。清单 3 给出了该例中相当简单的映射文件。

目前,JaxMe 要求直接修改该文件来改变映射。最常见的变化是您可能希望用自己的类代替生成的类。当然,您必须(至少对 JaxMe 的当前版本而言)生成默认的类, 然后再修改该文件。同样值得注意的是,实际上这种行为没有得到支持,尽管映射支持这样做,但是没有经过很好的测试,也没有很好的文档说明。
提示:将来的文章中我可能还要详细地讨论这种行为。如果对此感兴趣,请给我发电子邮件或者上传对本文的反馈意见,让我知道!这是了解对特定主题的兴趣要求的最好办法。
这是标准的 JAXB 性质文件,当然也经过了 JaxMe 的修改。其中只有一行,告诉 JAXB 工厂类使用 JaxMe 的实现类,如下所示:
javax.xml.bind.context.factory=org.apache.ws.jaxme.impl.JAXBContextImpl
对熟悉 JAXP 的读者而言,在实现方式上,这与 Xerces 要求 JAXP 体系结构完成其实现是完全相同的。
impl 子目录中的各个源文件都是由 JaxMe 创建的接口的具体实现。一般来说不用关心这些文件,它们处理文档的 XML 加工过程,将文档转换成 Java 中的等价物。
如果您喜欢刨根问底,那么可以告诉您这些类都是 SAX 类,因为 JaxMe 使用 SAX 解析 XML。事实上,Type 类(间接地)实现了 SAX 的 org.xml.sax.ContentHandler 接口。在源代码中您还会看到 startDocument() 和 characters() 这样的方法(都列在这里的话太长了)。
虽然您可能不想对这些类太费心思,但是对其有个基本的了解还是不错的。您将会在代码中使用它们(很快就会看到),您会发现理解这些类对于查错和调试很有帮助。
观察这些类的最后一个步骤就是编译它们。这似乎是显而易见的事,但是您恐怕难以相信那些因缺乏编译而造成的问题,或者类路径问题(稍后还会提到)。因此在使用这些类之前一定要编译它们。同样,我发现使用 Ant 来完成这项工作最简单,因此我使用 ant compile 来完成这项任务。
对于喜欢苦差事(或者只是爱好输入 javac )的人,类路径中一定要包括 jaxme-api.jar和 jaxme.jar。 jaxme-api.jar包含 JAXB API,而 jaxme.jar 则包含 JaxMe 实现类。在输出的时候,应该将所有的输出都放在基目录和编译后的 impl 目录中。最后,您可能希望复制所用的支持文件: Configuration.xml和 jaxb.properties。在运行时导入这些文件,以便对它们进行编组和解组。




回页首
您 会发现没有什么好的替代构建工具。好的工具可以为您节约反复处理类路径问题的大量时间,也不用您去记住特定的命令行选项。本文中遇到的几个问题都可以使用 Ant 来自动处理。我想花一点让您看一看我的 Ant 文件,这样您也可以把 Ant 结合到您的构建环境中。我以后的文章中也可以略过这些细节(艺多不压身,是不是?)。
首先,您会希望使用 JaxMe 模式编译器/类生成工具,用 org.apache.ws.jaxme.generator.Generator 接口表示。因此,您完全可以使用 Ant 的 java 目标创建该接口的一个实例。但是,这样做有点麻烦——需要在实现中进行硬编码,而且必须将构建文件和实现的变化混在一起。您可以将实现类定义为属性,但是 这样仍然存在非常低层的编码混合问题。对于使用 Ant 的人来说,所幸的是 JaxMe 包括用于在构建文件中插入类生成的 Ant taskdef (任务定义),它可以处理所有这些细节问题。假设您有一个定制的任务定义,如清单 4 所示:

只要将这个片段插入 Ant 构建文件,生成类就变得非常简单。您可以使用清单 5 中的 XML 完成这项工作。

生成类之后,现在需要编译并复制支持文件。清单 6 负责这项任务,它甚至还处理了类路径问题。

显然,如果能够清除所做的工作,然后重新开始新的工作常常是有益的。虽然这并非 JaxMe 特有的,但也值得看一看。通常的办法是通过一个称为 clean 的目标(target)进行清理,如清单 7 所示。

清单 8 是一个更大的 Ant 文件,它将这些成分集中到了一起。实际上这也是我一直在用的文件,该文件对于这里描述的所有内容都适用。

您需要改变 lib.jaxme 属性的值,然后就可以了。该例中只需要输入 ant generate 就可以从模式生成类。您应该把这类工具(以及 Ant)放在手边,因为它使得编译和处理微妙的类路径变得非常简单。




回页首
只要充分理解了 JaxMe 处理类生成的方式,就可以很容易的实现与 XML 的相互转化。我将在下一篇文章讨论这个问题,然后再介绍 JaxMe 某些专有的特性,比如使用数据库。在这之前先用映射和 Configuration.xml来打发时间吧,但愿您过得愉快(也需要发一两次火)并真正掌握 JaxMe 的工作原理。在这期间,我将开始撰写下一期的稿子,那时再见吧。




回页首
名字大小下载方法
x-pracdb4-code.zip 2KB  FTP|HTTP

关于下载方法的信息Get Adobe® Reader®
您可以参阅本文在 developerWorks 全球站点上的英文原文.
下载student.xsd 和 build.xml 的代码。
访问JaxMe网站,进一步了解这种新的 API。
请访问Java Architecture for XML Binding (JAXB)网页。
请参阅Apache Incubator,像 JaxMe 这样新的有创意的项目随时都会出现。
请参阅 Brett 关于数据绑定的完整著作, Java and XML Data Binding (O‘Reilly & Associates)。在 developerWorksDeveloper Bookstore还可以找到各种关于 XML 的书籍。
如何使用数据绑定轻松实现 XML 文档中存储的数据与 Java 对象的互相转换,请参阅 Daniel Steinberg 撰写的教程“使用 JAXB 进行数据绑定”( developerWorks,2003 年 5 月)。
要了解使用W3C XML Schema 或者 DTD grammars for XML 文档的代码生成实现 XML 数据绑定的几种方法,请阅读 Dennis Sosnoski 的文章“数据绑定,第 1 部分:代码生成方法 — JAXB 及其它”( developerWorks,2003 年 1 月)。
获取Jakarta Commons 包中的文本解析工具。
从 Sun 的网站上进一步了解XML API。
要了解如何通过 WebSphere Studio Application Developer V5.1 使用 JAXB 来开发企业应用程序,请阅读 Tilak Mitra 的这篇文章( developerWorks,2004 年 2 月)。
在 developerWorksXML和Java 技术专区可以找到更多数据绑定资源。
了解如何才能成为一名IBM 认证的 XML 及相关技术的开发人员。

 

Brett McLaughlin 从 Logo 时代(还记得那个小三角吗)就开始从事计算机。他目前专门使用 Java 相关技术构建应用程序基础设施。最近几年,他为 Nextel Communications 和 Allegiance Telecom, Inc. 实现了这些基础设施。Brett 是 Java Apache 项目 Turbine 的缔造者之一,该项目使用 Java servlet 为 Web 应用程序开发建立了可重用的组件体系结构。他还参与了 EJBoss 项目(一种开放源代码的 EJB 应用程序服务器)和 Cocoon(一种开放源代码的 XML Web 发布引擎)。