1

我有一个包含自定义标头的基于肥皂的 Web 服务的 WSDL:

<message name="Request">
    <part element="common:Request" name="Request"></part>
    <part element="common:myHeader" name="Header"></part>
</message>

<operation name="processRequest">
    <soap:operation soapAction=""/>
    <input>
        <soap:body parts="Request" use="literal"/>
        <soap:header message="tns:Request" part="Header" use="literal"></soap:header>
    </input>
    <output>
        <soap:body use="literal"/>
    </output>
</operation>

标头类型在单独的模式文件中定义:

<xs:element name="myHeader" nillable="false" type="tns:myHeaderType"/>

<xs:complexType name="myHeaderType">
    <xs:sequence minOccurs="1" maxOccurs="1">
        <xs:element name="JobID" type="tns:JobIDType" minOccurs="1" maxOccurs="1"/>
        <xs:element name="TransactionID" type="xs:string" minOccurs="1" maxOccurs="1"/>
    </xs:sequence>
</xs:complexType>

此外,我正在验证 的定义,myHeaderType以确保所需的元素在那里,满足格式约束等。这一切似乎都正常工作,因为格式正确的请求被接受,格式不正确的请求被拒绝。

我的问题出现在使用 Apache Axis(隐藏在专有工具后面)生成 Web 服务客户端的消费者身上。正如此处的另一个 StackOverflow 问题中所述,Axis 在 myHeader 上插入了 SOAP 标准允许的一些可选属性(据我所知):

<soapenv:Header>
    <com:myHeader soapenv:mustUnderstand="0" soapenv:actor="">
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
        <JobID>myJobId</JobID>
        <TransactionID>myTransactionId</TransactionID>
    </com:myHeader>
</soapenv:Header>

由于我的消费者正在使用的工具,修改 Axis 生成的存根以忽略这些属性是不可行的,正如其他地方所建议的那样。此外,如果我要声称自己是肥皂服务,我的服务似乎应该允许这些属性。我的问题是,如何修改我的标题定义以适应这些可选属性,并在理想情况下规划我可能没有预料到的属性。是否有可以为我的标头类型定义扩展的标准类型,或者这种情况的一般最佳实践?

4

2 回答 2

1

我今天找到了几个解决我的问题的方法。它们都解决了问题,但我对我的判断是否真的是两者中的更好没有信心,所以我将在此处介绍它们。

两种解决方案都以修改 的定义为中心,myHeaderType以便它可以容纳未预料到的 SOAP 定义的属性。

  1. 在 SOAP WSDL 模式定义 ( http://schemas.xmlsoap.org/wsdl/ ) 中,有一个名为的类型tExtensibleAttributesDocumented包括以下非常灵活的属性定义:

    <xs:anyAttribute namespace="##other" processContents="lax"/>
    

    通过扩展这种抽象类型,我能够将这种对意外属性的自由允许合并到我的类型中。这是生成的代码:

      <xs:complexType name="myHeaderType">
          <xs:complexContent>
              <xs:extension base="wsdl:tExtensibleAttributesDocumented">
                  <xs:sequence minOccurs="1" maxOccurs="1">
                      <xs:element name="JobID" type="tns:JobIDType" minOccurs="1" maxOccurs="1"/>
                      <xs:element name="TransactionID" type="xs:string" minOccurs="1" maxOccurs="1"/>
                  </xs:sequence>
              </xs:extension>
          </xs:complexContent>
      </xs:complexType>
    

    请注意,这不会检查mustUnderstandor的内容actor,并允许其他属性,包括完全垃圾,只要它来自我在 XML 请求中定义的命名空间。

  2. 另一种选择是直接<xs:anyAttribute>在我的类型中包含:

      <xs:complexType name="myHeaderType">
          <xs:sequence minOccurs="1" maxOccurs="1">
              <xs:element name="JobID" type="tns:JobIDType" minOccurs="1" maxOccurs="1"/>
              <xs:element name="TransactionID" type="xs:string" minOccurs="1" maxOccurs="1"/>
          </xs:sequence>
          <xs:anyAttribute namespace="##other" processContents="lax"/>
      </xs:complexType>
    

    据我所知,这具有基本相同的效果。

如果我不知道这些解决方案之间有任何细微的差异,我很想听听。如果这种情况有一个公认的标准,我找不到它。此解决方案的另一个弱点是我无法获取属性以根据它们在模式中的定义进行验证。更改processContents属性以strict防止处理定义明确的mustUnderstand属性actor

于 2012-08-03T21:16:05.280 回答
0

是的,您可以使用AltovaXMLSpy编辑器进行修改。功能性使用 30 天。

于 2012-08-02T21:48:56.847 回答