第 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>