第 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 绑定的扩展。请参阅 “XML 绑定命名空间”一节。
-
向您的合同添加标准 WSDL
绑定元素来保存 XML 绑定,为绑定指定一个唯一的名称,并指定代表正在绑定接口的 WSDLportType元素的名称。 -
将
xformat:binding子元素添加到binding元素,以标识消息正在作为纯 XML 文档处理,而无需 SOAP envelopes。 -
另外,还可将
xformat:binding元素的rootNode属性设置为有效的 QName。有关rootNode属性的影响的更多信息,请参阅 “wire 上的 XML 消息”一节。 -
对于绑定接口中定义的每个操作,请添加标准 WSDL
操作元素来存放操作消息的绑定信息。 对于添加到绑定的每个操作,添加
输入、输出和错误子元素,以表示操作使用的消息。这些元素与逻辑操作接口定义中定义的消息对应。
-
(可选)添加带有有效
rootNode属性的xformat:body元素到添加的输入、output和fault元素,以覆盖绑定级别上的rootNode设置的值。
如果您的任何消息没有部分,例如返回 void 的操作的输出消息,您必须为消息设置 rootNode 属性,以确保在 wire 上写入的消息有效,但空 XML 文档。
wire 上的 XML 消息
当您指定接口的消息将作为 XML 文档传递时,如果没有 SOAP 信封,则必须小心谨慎,以确保您的消息在线上写入有效的 XML 文档时。您还需要确保接收 XML 文档的非 Apache CXF 参与者了解 Apache CXF 生成的消息。
解决这两个问题的简单方法是在全局 xformat:binding 元素或单独的消息的 xformat:body 元素上使用可选的 rootNode 属性。rootNode 属性指定作为 Apache CXF 生成的 XML 文档的根节点元素的 QName。如果没有设置 rootNode 属性,当使用 rpc 风格消息时,Apache CXF 使用消息部分的 root 元素作为 root 元素,或使用消息部分名称作为 root 元素的一个元素。
例如,如果 rootNode 属性没有设置 例 10.1 “有效的 XML 绑定消息” 中定义的消息,则会生成带有 root 元素 lineNumber 的 XML 文档。
例 10.1. 有效的 XML 绑定消息
<type ... > ... <element name="operatorID" type="xsd:int"/> ... </types> <message name="operator"> <part name="lineNumber" element="ns1:operatorID"/> </message>
对于带有一个部分的消息,即使未设置 rootNode 属性,Apache CXF 始终也会生成有效的 XML 文档。但是,例 10.2 “无效的 XML 绑定消息” 的消息会生成无效的 XML 文档。
例 10.2. 无效的 XML 绑定消息
<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 文档” 中定义的消息生成与 例 10.2 “无效的 XML 绑定消息” 类似的 XML 文档。生成的 XML 文档无效,因为它有两个根元素: pairName 和 entryNum。
例 10.3. 无效的 XML 文档
<pairName> Fred&Linda </pairName> <entryNum> 123 </entryNum>
如果您设置了 rootNode 属性,如 例 10.4 “使用 rootNode 设置的 XML Binding” Apache CXF 所示,将嵌套指定根元素中的元素。在本例中,整个绑定定义了 rootNode 属性,并指定 root 元素将命名为 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 文档现在只有一个 root 元素。
例 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>