第 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:
子元素,以标识消息作为纯 XML 文档处理,但没有 SOAP envelopes。binding
-
另外,还可将
xformat:binding
元素的rootNode
属性设置为有效的 QName。有关rootNode
属性的效果的更多信息,请参阅 “线上的 XML 消息”一节。 -
对于每个在绑定接口中定义的操作,添加一个标准的 WSDL
操作
元素,以存放操作消息的绑定信息。 对于添加到绑定的每个操作,添加
输入
、输出和错误
子元素,以表示操作所使用的消息。这些元素对应于逻辑操作的接口定义中定义的消息。
-
(可选)将具有有效
rootNode
属性的xformat:body
元素添加到添加的输入
、输出
和故障元素中,以覆盖绑定级别的rootNode
设置值。
如果您的任何消息都没有部分,例如返回 void 的操作的输出消息,您必须为消息设置 rootNode
属性,以确保在线上写入的消息有效,但空 XML 文档。
线上的 XML 消息
当您指定接口的消息作为 XML 文档传递时,如果没有 SOAP envelope,则必须小心谨慎,以确保您的消息表单在有线上写时,确保消息形成有效的 XML 文档。您还需要确保接收 XML 文档的非 Apache CXF 参与者了解 Apache CXF 生成的消息。
解决这两个问题的简单方法是,在 global xformat:binding
元素上使用可选的 rootNode
属性,或者用于单个消息的 xformat:body
元素。rootNode
属性为元素指定 QName,充当由 Apache CXF 生成的 XML 文档的根节点。如果没有设置 rootNode
属性时,Apache CXF 使用消息部分的 root 元素,在使用 doc 风格消息时将消息部分名称用作 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 文档” 中定义的消息生成类似如下的 XML 文档。例 10.2 “无效的 XML 绑定消息”生成的 XML 文档无效,因为它有两个根元素: pairName
和 entryNum
。
例 10.3. 无效的 XML 文档
<pairName> Fred&Linda </pairName> <entryNum> 123 </entryNum>
如果您设置了 rootNode
属性,如 例 10.4 “带有 rootNode 设置的 XML 绑定” Apache CXF 所示,将在指定的根元素中嵌套元素。在本例中,rootNode
属性是针对整个绑定定义的,并指定根元素的名称为 entrants。
例 10.4. 带有 rootNode 设置的 XML 绑定
<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 属性设置
您还可以为每个单个消息设置 rootNode
属性,或者使用消息绑定中的 xformat:body
元素覆盖特定消息的全局设置。例如: 如果您希望 例 10.4 “带有 rootNode 设置的 XML 绑定” 中定义的输出消息具有与输入消息不同的根元素,您可以覆盖绑定的根元素,如 例 10.6 “Using xformat:body
” 所示。
例 10.6. Using 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>