第 3 章 定义服务使用的逻辑消息

摘要

服务由消息在调用其操作时进行交换定义。在 WSDL 合同中,这些消息通过使用 消息 元素来定义。这些消息由一个或多个使用 部分 元素定义的部分组成。

概述

服务的操作是通过指定调用操作时交换的逻辑消息来定义。这些逻辑消息定义通过网络作为 XML 文档传递的数据。它们包含属于方法调用一部分的所有参数。 使用合同中的 message 元素定义逻辑消息。每个逻辑消息由一个或多个部分组成,它们在 部分 元素中定义。

虽然您的消息可以列出各个参数作为单独的部分,但推荐的做法是只使用单个部分来封装操作所需的数据。

消息和参数列表

服务公开的每个操作只能有一个输入消息和一个输出信息。输入消息定义服务在调用操作时接收的所有信息。输出消息定义在操作完成时返回的所有数据。容错消息定义在发生错误时服务返回的数据。

此外,每个操作都可以具有任意数量的故障消息。故障消息定义服务遇到错误时返回的数据。这些消息通常仅有一个部分提供足够的信息供消费者理解该错误。

用于与旧系统集成的消息设计

如果您要将现有应用程序定义为服务,您必须确保实施该操作方法使用的每个参数都会在消息中表示。您还必须确保返回的值包含在操作的输出消息中。

定义消息的一种方法是 RPC 样式。使用 RPC 风格时,您可以在方法的参数列表中为每个参数定义一个部分。每条消息部分都基于合同元素中定义的 类型。您的输入消息包含方法中每个输入参数的一个部分。您的输出消息包含每个输出参数的一个部分,以及用于表示返回值的部分(如果需要)。如果参数同时是输入和输出参数,它将被列为输入消息和输出消息的一部分。

当服务启用使用 Tibco 或 CORBA 等传输的系统时,RPC 风格消息定义很有用。这些系统围绕流程和方法设计。因此,它们最容易使用类似参数列表的消息来建模。RPC 风格还在服务与应用程序间进行清晰映射。

SOAP 服务的消息设计

尽管 RPC 风格对于对现有系统建模非常有用,但该服务的社区很强大地选择被嵌套的文档样式。在嵌套文档样式中,每个消息都有单个部分。消息的部分引用在合同 类型 的元素中定义的 wrapper 元素。wrapper 元素具有以下特征:

  • 它是包含一系列元素的复杂类型。更多信息请参阅 第 2.5 节 “定义复杂数据类型”
  • 如果它是输入消息的打包程序:

    • 它有一个元素,用于各个方法的输入参数。
    • 其名称与与之关联的操作的名称相同。
  • 如果它是一个输出消息的打包程序:

    • 它为每个方法的输出参数和一个元素,每个方法的 inout 参数都有一个元素。
    • 其第一个元素表示方法的 return 参数。
    • 其名称是通过在与打包程序关联的操作名称中添加 Response 来生成的。

消息命名

合同中的每个消息都必须在其命名空间内具有唯一的名称。建议您使用以下命名规则:

  • 消息仅应由单个操作使用。
  • Request 附加到操作名称即可形成输入消息名称。
  • 通过将 Response 附加到操作名称来形成输出信息名称。
  • 容错消息名称应该代表故障的原因。

Message parts

Message 部分是逻辑消息的正式数据单元。每一部分使用 part 元素进行定义,由 name 属性和 type 属性识别,或者指定其数据类型的元素属性。数据类型属性列在 表 3.1 “部分数据类型属性” 中。

表 3.1. 部分数据类型属性

属性描述

element="elem_name"

部分的数据类型由名为 elem_name 的元素定义。

type="type_name"

部分的数据类型由名为 type_name 的类型定义。

消息可以重复使用部分名称。例如,如果方法有一个参数 foo,它通过引用传递,或者是 in/out,它可以是请求消息和响应消息的一部分,如 例 3.1 “重复使用部分” 所示。

例 3.1. 重复使用部分

<message name="fooRequest">
  <part name="foo" type="xsd:int"/>
<message>
<message name="fooReply">
  <part name="foo" type="xsd:int"/>
<message>

示例

例如,假设您有一个存储个人信息的服务器,并提供了一种根据员工的 ID 号返回员工数据的方法。查找数据的方法签名与 例 3.2 “personalInfo 查找方法” 类似。

例 3.2. personalInfo 查找方法

personalInfo lookup(long empId)

这个方法签名可以映射到 例 3.3 “RPC WSDL 消息定义” 中显示的 RPC 风格的 WSDL 片段。

例 3.3. RPC WSDL 消息定义

<message name="personalLookupRequest">
  <part name="empId" type="xsd:int"/>
<message/>
<message name="personalLookupResponse>
  <part name="return" element="xsd1:personalInfo"/>
<message/>

它还可映射到 例 3.4 “嵌套的文档 WSDL 消息定义” 中显示的嵌套式文档风格的 WSDL 片段。

例 3.4. 嵌套的文档 WSDL 消息定义

<wsdl:types>
  <xsd:schema ... >
  ...
  <element name="personalLookup">
    <complexType>
      <sequence>
        <element name="empID" type="xsd:int" />
      </sequence>
    </complexType>
  </element>
  <element name="personalLookupResponse">
    <complexType>
      <sequence>
        <element name="return" type="personalInfo" />
      </sequence>
    </complexType>
  </element>
  </schema>
</types>
<wsdl:message name="personalLookupRequest">
  <wsdl:part name="empId" element="xsd1:personalLookup"/>
<message/>
<wsdl:message name="personalLookupResponse">
  <wsdl:part name="return" element="xsd1:personalLookupResponse"/>
<message/>