第 10 章 使用 XML 文档

摘要

纯 XML 有效负载格式提供了 SOAP 绑定的一种替代方式,允许服务使用直接 XML 文档来交换数据,而无需增加 SOAP 信封。

XML 绑定命名空间

用于描述 XML 格式绑定的扩展在命名空间 http://cxf.apache.org/bindings/xformat 中定义。Apache CXF 工具使用前缀 xformat 来代表 XML 绑定扩展。在您的合同中添加以下行:

xmlns:xformat="http://cxf.apache.org/bindings/xformat"

手动编辑

将接口映射到纯 XML 有效负载格式,请执行以下操作:

  1. 添加命名空间声明,使其包含定义 XML 绑定的扩展。请参阅 “XML 绑定命名空间”一节
  2. 在您的合同中添加标准 WSDL 绑定 元素以存放 XML 绑定,为绑定指定 一个唯一名称,并指定代表接口绑定的 WSDL portType 元素的名称。
  3. xformat: binding 子元素添加到绑定元素中,以标识消息作为纯 XML 文档处理,而无需 SOAP envelopes。
  4. 另外,还可将 xformat:binding 元素的 rootNode 属性设置为有效的 QName。如需有关 rootNode 属性影响的更多信息,请参阅 “线路上的 XML 消息”一节
  5. 对于绑定接口中定义的每个操作,添加标准的 WSDL 操作 元素来保存操作消息的绑定信息。
  6. 对于添加到绑定的每个操作,添加 输入输出和错误 子元素来代表操作使用的消息。

    这些元素对应于逻辑操作接口定义中定义的消息。

  7. (可选)添加带有有效 rootNode 属性的 xformat:body 元素到添加的 输入输出fault 元素,以覆盖绑定级别设置的 rootNode 的值。
注意

如果有任何消息没有相关部分,例如返回无效操作的输出消息,则必须为消息设置 rootNode 属性,以确保 wire 上写入的消息是有效的,但为空,XML 文档。

线路上的 XML 消息

当您指定接口的信息要作为 XML 文档(没有 SOAP 信封)时,您必须小心谨慎,以确保当它们在线路上写入时,您的消息形成有效的 XML 文档。您还需要确保接收 XML 文档的非 Apache CXF 参与者了解 Apache CXF 生成的消息。

解决了这两个问题的简单方法是,使用 global xformat:binding 元素上的可选 rootNode 属性或单个消息的 xformat:body 元素。rootNode 属性指定作为 Apache CXF 生成的 XML 文档的根节点元素的 QName。如果没有设置 rootNode 属性时,在使用 doc 风格消息时,Apache CXF 将消息部分的 root 元素用作根元素,或者使用消息部分名称作为 rpc 样式消息时的 root 元素。

例如,如果 rootNode 属性未设置 例 10.1 “有效的 XML Binding Message” 中定义的消息,则会使用根元素 lineNumber 生成 XML 文档。

例 10.1. 有效的 XML Binding Message

<type ... >
  ...
  <element name="operatorID" type="xsd:int"/>
  ...
</types>
<message name="operator">
  <part name="lineNumber" element="ns1:operatorID"/>
</message>

对于一个部分的消息,Apache CXF 将始终生成有效的 XML 文档,即使未设置 rootNode 属性。但是,例 10.2 “无效的 XML Binding 消息” 中的信息会生成无效的 XML 文档。

例 10.2. 无效的 XML Binding 消息

<types>
  ...
  <element name="pairName" type="xsd:string"/>
  <element name="entryNum" type="xsd:int"/>
  ...
</types>

<message name="matildas">
  <part name="dancing" element="ns1:pairName"/>
  <part name="number" element="ns1:entryNum"/>
</message>

如果没有 XML 绑定中指定的 rootNode 属性,Apache CXF 将生成与 例 10.3 “无效的 XML 文档” 中定义的消息类似的 XML 文档。例 10.2 “无效的 XML Binding 消息”生成的 XML 文档无效,因为它有两个根元素: pairNameentryNum

例 10.3. 无效的 XML 文档

<pairName>
  Fred&Linda
</pairName>
<entryNum>
  123
</entryNum>

如果您设置了 rootNode 属性,如 例 10.4 “带有 rootNode 集的 XML Binding” Apache CXF 所示,则会将元素嵌套到指定的根元素中。在本例中,为整个绑定定义了 rootNode 属性,并指定根元素将命名为 entrants。

例 10.4. 带有 rootNode 集的 XML Binding

<portType name="danceParty">
  <operation name="register">
    <input message="tns:matildas" name="contestant"/>
  </operation>
</portType>

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered"/>
</binding>

从输入消息生成的 XML 文档类似于 例 10.5 “使用 rootNode 属性生成的 XML 文档”。请注意,XML 文档现在只有一个根元素。

例 10.5. 使用 rootNode 属性生成的 XML 文档

<entrants>
  <pairName>
    Fred&Linda
  <entryNum>
    123
  </entryNum>
</entrants>

覆盖绑定的 rootNode 属性设置

您还可以使用消息中的 xformat:body 元素在消息绑定中为每个单独消息设置 rootNode 属性,或者覆盖特定消息的全局设置。例如,如果您想要 例 10.4 “带有 rootNode 集的 XML Binding” 中定义的输出消息与输入消息不同的 root 元素,您可以覆盖绑定的根元素,如 例 10.6 “使用 xformat:body 所示。

例 10.6. 使用 xformat:body

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered">
      <xformat:body rootNode="entryStatus" />
    </output>
  </operation>
</binding>