设计面向文档的服务
作者:Sean Brydon、Smitha Kangath 及 Sameer Tyagi
问题描述
Java[TM] 2 Platform, Enterprise Edition(J2EE[TM] 平台)1.4 应用程序可能需要使用基于 XML 的远程过程调用的 Java API (JAX-RPC) 传递 XML 文档。例如,某个应用程序可能具有接收 PurchaseOrder.xml 文档或接收 Invoice.xml 文档的服务。这种解决方案主要以基于文档的服务为主,该服务是以处理文档问题为模型的。我们专注于基于文档的服务,而不是基于过程的服务。开发者可能需要创建 Web 服务,在这种服务中,数据是以符合预先制定的 XML 结构的 XML 文档格式进行交换的。这些结构可能是应用程序特有的,或者由垂直行业标准机构定义。在此解决方案中,我们不对 XML 文档的同步或异步处理加以区分,而是专注于传递 XML 文档,对处理模式不予以考虑。这种解决方案适用于各种类型的服务处理模式。其中一项关键的设计选择是确定接口工件中表示正在交换的 XML 业务文档所用的类型。
开发者在设计 Web 服务交互环境(客户端和服务在其中交换 XML 文档)时,需要选择一种表示服务接口中的 XML 文档的类型。被交换为参数或返回值的 XML 文档的类型在服务的 WSDL、服务的 Java 接口和实现类中表示。当设计接收 XML 文档(如 PurchaseOrder.xml)的服务时,接口和 WSDL 文件必须选择一种类型来表示 XML 文档。例如,可以使用字符串作为订单 xml 文档的类型,或者使用对象样式,将所有文档详细信息和结构详细信息的描述嵌入到接口中,还可以通过选择 xsd:anyType 或其他类型选项,使用 XML 片段表示订单文档。这是设计服务时的一个关键决策。
为服务接口选择表示 XML 文档的类型会带来多方面的影响。例如,在服务上,它将更改 WSDL 文件中的参数类型(以及返回值)、Java 接口和实现类中的参数类型、对接收的文档的处理(如文档验证)、从 XML 绑定到 Java 对象等。表示接口和服务的 WSDL 中的 XML 文档的设计类型选择也会影响服务客户端。例如,在客户端它会更改客户端代码,因为它需要为交换的 XML 文档构造参数。它还会影响线上序列化文档的特性。而对于返回的文档,它会影响接收的文档的处理方式。这些都是开发者在服务接口中选择表示交换的 XML 文档的类型时需要考虑的一些问题。
另一个需要考虑的问题是,某些环境可能计划对服务使用管理或监视工具,特别是在 SOAP 层,监视工具对于某些类型服务的监视效果不像其他类型那样透明。例如,这些工具可能很难处理字符串,因为字符串在线上的表示包含一些额外的编码信息。因此签名的线层视图可能会影响监视的功能。当然,公开参数类型的选择也可能影响互操作性,所以这也是一个需要考虑的问题。
此解决方案适用于以下情况:
- 开发者可能需要创建以 XML 文档格式表示的交换数据的 Web 服务。
- 开发者可能需要将 Web 服务与其他基于文档的应用程序相集成。
- 开发者使用 J2EE 1.4 技术(例如 JAX-RPC)进行 Web 服务交互。
- 开发者可能使用 Java-to-WSDL 开发技术(先在 Java 接口中开发,然后生成 WSDL)或 WSDL-to-Java 开发技术(先开发 WSDL,然后生成 Java 接口)。
解决方案
开发者在设计 Web 服务交互环境(客户端和服务在其中交换 XML 文档)时,需要选择一种表示服务接口中的 XML 文档的类型。类型的选择会带来多方面的影响。
此解决方案简要介绍了不同的策略并对其进行了比较,然后提供了一些选择策略的指导原则。以交互层为主,而不是 XML 文档的业务处理。目录中的其他相关项对每种策略进行了详细的定义,因此强烈建议您查看每个相关项及其应用程序。涉及了以下策略及示例应用程序:
以后可能会包括一些其他的策略,例如在 SOAP 正文中使用 base64Encoded 或原始字节,而不使用数据绑定。
现在简单地介绍一下该问题及解决方案涉及的内容:
- 客户端向服务发出 Web 服务请求。客户端需要构造 XML 文档,然后将文档转换为服务 WSDL 中定义的适当类型,接着在客户端调用 Java 方法来传递 XML 文档,并对服务进行调用。
- XML 文档是被传递的有效负载,例如,订单的内容。
- 用于描述服务的 WSDL 文件。
- 服务端点接口类。它将是服务的 Java 接口。
- 服务端点实现类。它将是 JAX-RPC 端点或 EJB 端点的实现类。
- 为 XML 文档选择参数和返回值的类型。这种类型将反映在描述服务的 WSDL 文件、服务端点接口类以及服务端点实现类中。
- XML 文档的序列化(线上)表示。
表示在客户端和 Web 服务之间交换的 XML 文档类型的选择可能会影响上述所有因素。例如,所选的类型需要被包含在 WSDL 文件中,所以会影响所有服务实现生成的 Java 类,而且还可能影响添加 Web 服务层的现有应用程序对象模型。同时也会影响访问服务的客户端应用程序,因为它们需要为服务 WSDL 文件中的类型生成 Java 类,并且需要将它们自身的客户端数据模型转换为各种服务类型。所选择的类型将影响服务的互操作性。该类型还会影响 JAX-RPC 运行环境是否可以执行绑定到 Java 对象,或者影响您的应用程序代码是否需要执行该绑定。
总结和建议
在选择服务接口的类型时,我们提供如下建议:
- 大多数情况下,您的服务应当使用结构定义的类型。这是最通用的情况。大多数服务对传递到服务并由服务返回的 XML 文档具有明确的类型。之所以能够很好地使用此策略,就是因为在服务 WSDL 文件和关联的结构文件中对服务进行了更全面的描述。这与使用字符串表示文档的类型相反,因为使用字符串类型会隐藏与服务交换的 XML 文档的结构信息。例如,如果服务需要接收 purchaseorder.xml 文档的方法,并使用了字符串,那么服务描述将会是 WSDL 文件中的一个字符串,它不能告知您这个服务需要获得的任何有关文档的信息,这使客户端难于使用这项服务。使用结构定义的类型的另一个好处是可以使用 JAX-RPC 运行环境绑定到 Java 对象,从而减少了应用程序的某些编码工作。
- 如果要开发中介服务或代理服务,则应当将服务设计为使用 xsd:any 来表示要交换的 XML 文档。在这种情况下,服务将创建一种可接收多种类型文档的通用服务方法。
- 如果不希望 XML 文档成为 SOAP 消息中有效负载的一部分(例如,在交换一个大图像时),则使用附件会很有帮助。但请注意,现在它不能在许多系统中互操作。
- 应当避免使用字符串表示要交换的 XML 文档。
表 1 总结了选择表示与面向文档的 Web 服务交换 XML 文档的类型的各种策略。Java BluePrints Solutions Catalog 中的其他项更详细地描述了这些主题。
策略
|
优点
|
缺点
|
使用结构定义的类型 (doc-literal 样式)
|
- 具有互操作性。
- 在使用 XML 文档时可验证结构。
- 比编码格式样式性能好。
|
- 不能直接使用定制绑定或绑定框架。
- 服务接口清晰地描述了所需的文档类型。这使得客户端更容易了解 WSDL 文件。
|
使用字符串
|
- 简单,如同编写一个 "Hello World" 应用程序。
|
- 无法使用运行时提供的结构验证,直到服务读取内存中的文档并尝试处理它时才能识别文档的错误。
- 服务接口不是描述性的,因为文档类型仅仅是一个常规字符串。
|
使用 xsd:any
|
- xsd:any 的映射已经被标准化为使用 JAX-RPC 1.1 映射到 SOAPElement。
尽管元素在 WSDL 中命名(例如,BusinessDocumentRequest),并且传递的业务文档出现在这些线上元素的内部,但是 Web 服务的客户端仍然能够处理整个 XML 文档并维护结构的完整性,而无须包含这些元素下的文档内容(对于 anyType 策略,情况有所不同)。
|
- 要求开发者使用低级的 XML 文档,因为目前他们必须创建和处理 SOAPElement 对象。
- WSDL 和文档之间没有任何关联性,因为定义文档的结构不是直接引用的。
- 需要预先确定结构内容。服务提供商和用户都需要预先了解有效负载的内容,因为 WSDL 文件未对所需文档的结构进行描述。
|
使用 xsd:anyType
|
- 允许将操作和有效负载一起传递。当创建多态处理程序,该应用程序接收使用同一操作的多种文档类型时,可以使用此策略。例如,对采用不同结构的订单和发票执行搜索操作的单一服务。
|
- JAX-RPC 规范没有为 xsd:anyType 定义标准的 Java 映射,因此不是所有的实现都像 Java WSDP 那样运行,必须将 xsd:anyType 映射到 SOAPElement。实际上,对于实现而言,xsd:anyType 支持是可选的。
- 因为 anyType 实际定义了 WSDL 中命名的元素的数据类型,SOAP 正文中所传递的业务文档位于 WSDL 标识的该元素中。例如,PurchaseOrder 位于 BusinessDocumentRequest 元素内。这意味着现在被传递的文档必须:
- 在 WSDL 中标识其根元素
- 或者适当地构造或飞速地封装在元素中
|
使用附件
|
- 对于采用不受 Web 服务端点支持的语言表示的结构的文档,或者禁止在 SOAP 消息信息集(如基于 DTD 结构的文档类型声明 <!DOCTYPE>)中出现的文档,非常有用。
- 对于大型文档非常有用(可以进行压缩和解压缩)。
- 可以使用处理程序在附件中生成其他工具,例如客户端处理程序,它使用口令将定制加密添加到附件中,然后使用 GZIP 算法对其进行压缩。相应的服务器端处理程序从附件中解压缩内容,然后使用基于口令的同一加密算法对内容进行解密。
|
- 互操作性:并不是所有的供应商都支持附件。例如,.NET 通过扩展包使用其自身的机制,并且不能处理基于 WS-I 附件配置文件的 MIME 附件。
|
表 1:不同策略的比较
除了表 1 中列出的策略外,还有可以在某些情况下使用的其他变更和其他策略。例如,在某些情况下,您可能不希望使用 JAX-RPC 的绑定机制,并可能选择不使用任何数据绑定。如果希望与类似 JAXB 的 API 集成并使其执行绑定,则这是很有用的。此类方法的缺点是只有此运行时才具有该行为。例如,Java Web Services Developer Pack 允许使用 –nodatabinding
开关。其他实现可能不支持这样的功能。可以尝试的其他变更是使用 base64 编码。当 XML 文档包含 SOAP 消息信息集或运行时实现不支持的字符或声明时,它非常有用。例如 DTD 声明和特定于语言环境的字符编码等。请注意,这存在互操作性问题。虽然这些选项和其他选项是可用的,但是一般说来最好按照总结和建议部分中的准则进行操作。
参考资料
有关本主题的详细信息(包括本文档中论述的各种策略的详细解决方案和示例应用程序),请参阅以下资料:
© Sun Microsystems 2005。Java BluePrints Solutions Catalog 中的所有内容受版权保护,未经 Sun Microsystems 的明确书面许可,不得在其他产品中发布。