面对互用性的挑战 在最基本的层次上实现应用程序平台之间的互用性要涉及到数据的交换 当实现一个 NET 和 JEE 互用性项目时面临三种主要的数据交换挑战 这三个挑战如下 ; 原始数据类型映射 ; 不存在的数据类型 ; 复杂数据类型 注原始数据类型是基于 NET 或 Java 的基本类型系统的组件例如整型字符串双精度等 所有的挑战都涉及到类型兼容性并有可能阻碍或阻止数据传输 这三个挑战分解如下 ; 原始数据类型映射 鈥_ 您可能知道String类型在 CLR 和 Java 中都存在 然而这并不意味着 Java 中的 javalangString 完全映射为 NET 中的 SystemString 如果示例公开 javalangString您如何将之映射为 CLR 中的相当成分? ; 不存在的数据类型 鈥_ 如何映射一个平台上有而另一个平台上没有的数据类型? 例如SystemCollectionsSpecializedHybridDictionary 是一个在 CLR 中被证实存在的数据类型但在 Java 中却没有相似的数据类型 Java 中存在类似情况例如 JavautilVector它在 NET 中没有相似的数据类型 ; 复杂数据类型鈥_ 您的应用程序可能公开复杂数据类型由数量众多的原始数据类型或者嵌套的原始数据类型组成 此时需要公开复杂数据类型以便其他平台可以使用它 考虑如图 所示的集成一个 ASPNET 表示层和一个 JEE 业务层的示例 在此示例中JEE 业务层中的一个 EJB 公开了一个 ASPNET 表示层随后调用的方法 在一个生产应用程序中该返回数据不可能是简单的Hello World字符串它可能包含复杂元素 图 ASPNET 表示层连接到 JEE 业务层幸运的是已经存在许多方法可使应用程序在不同平台之间交换不同类型的数据并且第 章和第 章将详细地描述这些选择 然而在能够在两个平台间建立连接之前您必须在它们试图进行交换之前确保双方理解特定的数据类型除此之外也有一个使双方都可以使用的传递数据的方法 下一部分讲述如何使用序列化实现该传递 使用序列化 序列化是使一个对象或类编码成为永久的或可传输状态的过程 这使您接受一个复杂数据类型然后编码保存传递和解码并可能使用一个单独的进程处理解码 有两个主要的序列化类型 ; 二进制序列化 鈥_ 接受数据类型并且将其转换为二进制流 ; XML 序列化 鈥_ 将数据类型转换为可以随后转换为 XML 文档的 XML 流 可以从任一种序列化类型中接受输出并将其存储在内存中放在文件中还可以通过网络连接进行传输 例如您的应用程序可能有一个已经定义的复杂数据类型 CustomerData它存储着有关客户的信息(如姓名地址电话号码等) 可以使用序列化将 CustomerData 数据类型转换为一个二进制或 XML 流这样您可以跨越进程边界进行传输或者将它保存为一个文件稍候使用 当该对象存在于二进制或 XML 格式中时就已经被序列化了 反序列化是一个将已经序列化的对象转换回它原始形式的过程 通常将对象反序列化为它们的原始类型 因此如果将 CustomerData 数据类型序列化为一个二进制流或一个 XML 文档能够将其反序列化回数据类型 CustomerData 而不能反序列化为数据类型 OrderDataOrderData NET和 JEE 在同一平台内应用程序间的数据交换都使用序列化 通过将序列化对象传递给其他平台以进行反序列化还可以使用序列化在不同平台上的应用程序间交换数据 以下部分考查如何在 NET 和 Java 上实现二进制和 XML 序列化 理解二进制序列化 二进制序列化是接受一种复杂数据类型(或对象)并将其编码为一个二进制流更改为永久状态传输然后解码(反序列化)回原始复杂数据类型的过程 Java 和 NET 两者都包含一个能将任何可序列化的数据类型转换为一个字节流的二进制序列化程序 各个平台上执行该序列化的类是相似的并且实现起来很简单 对 NET 和 Java 两者的二进制序列化而言首先必须使用一个标签以指示要序列化一个类型 在 NET 中可以使用 [Serializable] 属性或实现 ISerializable 接口 在 Java 中同样的方法是使用类实现 javaioserializable 不幸的是NET 和 Java 的序列化程序不兼容 因此无法将由 Java 序列化程序序列化的 CustomerData 对象直接流式传输到 NET 版本中去反之亦然 即使可以这样做还是要面对如下挑战让 NET 框架应用程序理解 Java 序列化程序产生的 CustomerData 对象 NET 一方可能没有一个等同的 CustomerData 数据类型来接受来自 Java 方的 CustomerData 反序列化对象 只要使用同样的格式化程序执行对象的序列化和反序列化就可以 使用二进制序列化程序连接 NET 到 Java 创建来自数据类型的字节流格式必须与接收字节流并且重新构造对象的格式完全匹配 有两种可以用来避免默认的 JEE 和 NET 二进制序列化程序不兼容的方法 它们是: ; 创建一个在 Java 和 NET 中共享相同格式选项的自定义序列化程序 ; 在 NET 框架中使用一个处理二进制格式化程序的第三方产品如 JaNET 或 JNBridgePro 有关使用 JaNET 和 JNBridgePro 实现二进制序列化的更多信息请参阅第 章互用性技术 点对点 理解 XML 序列化 XML 序列化是接受一个复杂数据类型(或对象)并将其解码为 XML 流的过程 然后可以将 XML 流转变为一个 XML 文档形式的持久化状态进行传输再将其解码(反序列化)回其原始复杂数据类型(或对象) 为了理解 XML 序列化过程必须对 XML 有一个基本的了解 XML 是一个基于文本的包含结构化的和可扩展数据的文档标记语言 因为 XML 是基于文本的所以可以像一个正常的文本一样读它并且因为它是可扩展的所以可以使用它描述几乎所有的信息类型 因此 XML 文档可以包括 ; 文本 ; 图片 ; 程序设置 ; 数据架构 ; 批注 ; 插入 XML 文档也可以包括关于如何使用文档自身中的数据的指导 有关 XML 的更多信息请参阅 Microsoft XML Web site 在理解二进制序列化一节中您可以看到 NET 和 Java 平台的二进制序列化程序是如何互相不兼容的 然而XML 是与平台无关的 如果在一个平台中可以将一个对象或数据类型序列化为 XML 文档应该很容易读取理解和反序列化该文档为另一个平台的对象或数据类型 不幸的是并非总是如此但在大多数情况下 XML 序列化的确提供了一个互用性通道 分析 XML 文档 在 NET 和 JEE 内有几种不同的方法可以读写和编辑 XML 文档 该过程就是 XML 分析并且两个平台都具有稳定成熟的 XML 分析器 使用分析器您可以在人工地从一个 XML 文档中读取数据的应用程序内编写代码然后将数据插入到一个复杂数据类型对象 例如可以使用分析从 JEE 应用程序产生的 XML 文档中读取数据然后将数据插入到 NET 数据类型 分析允许在 NET 和 JEE 之间交换数据 读写 XML 文档的分析器通常主要分三种类型 ; 双方平台上的文档对象模型 (DOM) ; 仅在 Java 上的用于 XML 的简单 API (SAX) ; 仅在 NET 上的 Pull model 分析 DOM XML 分析器将整个文档加载到内存这具有一些优点也有一些缺点 整个文档位于内存中可以简单快速地遍历 XML 层但大量的文档会因为内存的消耗而影响性能和响应 SAX 只根据需要读取 XML 文件的一部分 由于是按需要读文件则对性能的影响较小但由于阻止向后分析而降低了灵活性 Pull model 分析使用一个只进只读的 XmlReader 游标XMLReader 提供快速无缓存的流去访问输入数据允许提取数据和忽略不感兴趣的记录 因为 XmlReader 处于 pull model必要时应用程序可从读取器中提取节点 Pull model 提供了一些便利如状态管理多输入流避免额外的字符串复制以及有选择性地处理 有关使用 XmlReader 的更多信息请参阅 MSDN 上的Reading XML with the XmlReader SystemXml 命名空间提供 XmlDocument 和 XmlElement 两个类使您能够在 NET 中分析 XML 还提供一些方法能够在 XML 文档内添加和修改元素并且遍历那些文档 在 Java 中可以使用 Document 和 Element 类达成相似的结果 XML 分析的局限性 您需要了解一些 XML 分析的局限性 当从一个 XML 文档访问和读取不同的数据元素时分析工作进行正常 然而对文档本身操作信息可能很快就会变得很困难 而且分析器没有内部方法可用于将 XML 文档中的对象映射为 Java 或 NET 中的类 将 XML 文档中的数据映射为应用程序的对象和类中需要将 XML 序列化 XML 分析被认为是一种实现 XML 序列化的低效方法并且不建议使用此方法作为在 NET 和 Java 间交换 XML 数据的方法 |