2

假设我有一个 WSDL,它定义了一个接受复杂类型的操作,非常常见的 webmethod 东西,比如:

  <xs:element name="createBill">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" name="customer" nillable="true" type="xs:string" />
        <xs:element minOccurs="0" name="billId"   nillable="true" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <wsdl:message name="createBillRequest">
    <wsdl:part name="parameters" element="ns:createBill" />
  </wsdl:message>

  <wsdl:operation name="creatBill">
    <wsdl:input wsaw:Action="urn:createBill" message="axis2:createBillRequest" />
    ...
  </wsdl:operation>

两种不同调用的 WebServices 标准实现规则是什么,一个指定 billId 为xsi:nil,另一个完全省略节点?

<creatBill ...>
   <customer>1332400</customer>
   <billId xsi:nil="true"/>
</createBill>

vs

<creatBill ...>
   <customer>1332400</customer>
</createBill>

为了揭示更多背景,我对一个 Java 人有意见。他的 Web 服务是在 Axis2 中完成的,并且(出于对我来说奇怪的原因)处理 bill 元素的省略与 nil 值不同。我的主张是它们是相同的,并且在两种情况下它的行为应该相同(例如,创建一个动态的 billID)。他的说法是它不一样,他只在节点丢失时生成动态 ID,否则在节点被取消时返回错误(“billId 丢失”)。

我对他的说法的实际问题是 .NET 中的 WCF 和 WS 堆栈都将它们视为一个并且相同,甚至没有规定省略可空参数,这使得我几乎不可能在不编写我的代码的情况下实现客户端自己的 WS-stack 以及他实现的 WS-Security。就目前而言,我只能调用指定 null 的服务:

serv.createBill("1332400", null);
serv.createBill("1332400"); // ERROR: no such method

我什至不明白他是如何在 Java 中实现服务器端的,因此一个 Web 方法具有不同的调用模式,当省略节点时,Axis2 设置的 billID 参数是什么?他非常不合作,我需要一些论据(如果有的话)向他提出,然后再向他的经理提出,因为他们签订了支持合同。

既然我们不能都对,那么有谁知道这里的 WS 标准规定了什么?谁对标准有过错?我不是开始讨论 wcf 与轴火焰(请不要),我需要从 SOAP/WSDL 标准和规范的角度来看待这个问题,作为两者的父级。

4

2 回答 2

3

您的 Web 服务使用文档/文字样式。在这种情况下,Web 服务规范只要求消息内容(更具体地说是 SOAP 主体的单个子项)由 XML Schema 元素声明来描述,当然它也符合该声明。现在,XML Schema 确实允许同时使用 minOccurs="0" 和 nillable="true",但是规范并没有将元素的缺失与 xsi:nil="true 的元素的缺失附加任何特殊含义"; 特别是它没有声明这两种情况是等价的。由模式的设计者来定义这两种情况的含义。

另请注意,没有描述如何将 WSDL 和模式转换为特定语言结构的通用标准。

话虽如此,将 minOccurs="0" 和 nillable="true" 放在一起是有问题的,因为大多数语言只有一个概念,即空值,来表示值的缺失。如果使用 minOccurs="0" 或 nillable="true" 声明元素,则使用 null 值效果很好,但没有自然的方法来处理同时声明的元素。如以下问题所述,JAX-WS 规范解决了这个问题:

Jaxb 生成的类使用 JAXBElement 而不是指定的类型

与 JAX-WS 相比,其他一些特定于语言的 Web 服务绑定约定没有正确解决这个问题,并且将 minOccurs="0" 与 nillable="true" 一起使用通常会导致互操作性问题。因此,这应该被认为是一种不好的做法,但不幸的是,Web 服务规范中没有任何内容禁止这样做。

于 2012-09-06T09:35:35.097 回答
0

不能说 Axis 服务是否符合某些可空值的 WS 标准,但您可以通过设置DataMember 属性的 EmitDefaultValue 设置来调整 WCF 客户端生成的代码。如果将其设置为 false,则当可空类型的值为 null 时,WCF 将不会创建相应的 XML 元素,这似乎是服务正在寻找的。

于 2012-09-05T12:29:47.397 回答