5

我正在开发一个与第 3 方集成的 SOAP 应用程序。我觉得这个第三方的 WSDL 很奇怪。我对 SOAP 很陌生,所以如果它没有损坏,我不想去要求他们修复它。以下是我注意到的一些我认为错误的事情,尽管我确信它在技术上是一个有效的文档(因此我在标题中写了“最佳实践”)。另外,我使用 gSOAP 作为我的 SOAP 库,这可能就是为什么我认为其中一些东西很奇怪(我对 gSOAP 的了解甚至比对 SOAP 的了解还要新)。

  1. 它们在同一个 WSDL 中为 SOAP 1.1 和 SOAP 1.2 指定了接口。这会导致 gSOAP 生成两倍于它需要的类,因为我只打算使用 1.2。

  2. 他们所有的命名空间都是http://tempuri.org. 那不应该是这样的,对吧?

  3. 尽管定义了一堆 RPC 调用,但它们的 WSDL 使用文档格式。我正在考虑要求他们切换到 RPC 格式,因为 gSOAP 似乎不会生成将 C++ 类型参数用于文档格式的方法。相反,它为每个 API 函数的输入和响应数据创建一个新类。如果我不能解决这个问题,我将不得不编写另一层包裹 gSOAP 的东西,以便为我的应用程序的其余部分提供合理的 API。此外,AFAICT,如果他们切换到 RPC,将来回传输的 XML 将与现在完全相同,所以我认为这并不困难。

  4. 元素具有 minOccurs = 0 但是当我在没有它们的情况下提交请求时,我得到返回的错误表明它们是必需的(有时甚至是空指针异常的堆栈跟踪)。如果需要,他们应该将它们指定为 minOccurs = 1,对吗?

  5. 几乎所有的 Web 服务函数都指定了一个响应,其中包括一个表示成功的整数(实际上是一个布尔值)和一个错误消息字符串。他们应该为此使用 SOAP 错误吗?我认为如果它是一个错误,我的应用程序会更容易处理,因为 gSOAP 会让我很容易地解决这个问题(并简单地打印错误消息)。

当然,我不希望这家第 3 方公司仅仅因为我要求他们就改变他们的 WSDL。至少我会学到一些东西……据我所知,这些都不是错误的,甚至没有问题。谢谢你的帮助。

4

6 回答 6

4

我想对创建 WSDL 的最佳实践稍微概括一点:

1. 契约优先开发
与 James 相比,我强烈强调契约优先方法的使用,因为它使开发人员能够使用 XML 的全部功能(限制、模式等),并且从那里它是公平的易于为任何编程语言生成代码。另一个原因是 <wsdl:types> 中的模式是两个系统之间相互交谈的契约。如果开发人员从代码创建 WSDL,可能会引入对特定编程语言的技术依赖(数据类型,...)。

2. 文档/文字样式
RPC 编码的 SOAP 的验证可能很棘手,XPATH 查询和 XSLT 转换也是不可能的,而且这种样式无论如何都被弃用了。

RPC/literal 也会导致验证 XML 的问题(考虑到某些命名约定)。一些 SOAP 引擎丢弃了模式定义的名称空间,因此验证变得不可能。

使用 Document/literal 样式,SOAP 主体完全作为 XML 文档处理,可以以标准方式验证、转换和查询。

3. 关注点
分离 通过使用<import..> 和<include..> 指令将模式定义与WSDL 文件本身分离。这促进了模式的重用和将命名空间分离到不同的 .xsd 文件中,并且还减小了文件的大小;)

于 2009-05-18T15:31:55.980 回答
3

1 - 他们可能认为这是一项功能。:-)

2 - 这太可怕了。

3 - 很多人推荐这个。它被称为包装格式。

4 - 你是对的。

5 - 这取决于。从理论上讲,您可能是正确的,但实际上许多 SOAP 工具包对 SOAP 错误没有很好的支持,因此它们可能故意选择不使用异常。

于 2008-11-11T23:26:09.773 回答
2

在我看来,您尝试与之交互的第三方也不知道 Web 服务。

根据您的描述,这听起来非常典型的 Microsoft ASP.NET Web 服务实现,第三方编写了一点 VB 或 C# 来接口他们必须提供的东西,将其推送到 ASP.NET 服务器并调用它,具体取决于在 ASP.NET 引擎上根据请求自动生成 WSDL。

您可以要求他们不要提供 SOAP 1.1 定义,但我认为他们不会帮助您,因为他们不知道如何提供。你可以问他们为什么命名空间是 tempuri.org,我相信他们的回答会是“我们必须调查一下”,而他们真正想说的是“是吗??” 因为他们也不知道为什么。

命名空间由代码中的编译器指令控制,并且 tempuri.org 是 Microsoft 默认的(不记得它叫什么 atm sorry)。当然,命名空间的值并不重要(除了看起来很奇怪),因为它实际上只是为了为变量名称解析提供唯一的字符串标识符。也许其他东西可以以类似的方式控制,我不知道,我真的不知道 Web 服务或 ASP.NET 或任何那些东西,我自己不是该技术的忠实粉丝。

于 2008-11-13T20:04:06.773 回答
1

首先,没有人真正编写 WSDL——它是由工具生成的。您的供应商工具可能会为命名空间插入正确的 url,并且可能有一些单选按钮说——V1.0、V1.1、两者。供应商可能有一些现有的非 SOAP 代码并使用一些工具将它们包装为 SOAP 服务。

没有人写 WSDL,所以你不应该读它!获得一个像样的工具集,像 SOAPUI 之类的东西将解码 WSDL 并允许您浏览它而不会爆炸。它是 Java,但无论您使用哪种语言编写代码,它都是最好的测试工具。

我的 SOA 经验主要是在 Java 中,就库和工具而言,您可以选择太多。C++ 在这方面可能还不够成熟,但听起来确实问题出在工具选择上,而不是 WSDL 上。在现实世界中,您将看到不太完美的 WSDL,因此您的工具应该能够以合理的方式处理它。

于 2008-11-18T15:38:21.067 回答
1

刚才遇到这个,发现必须正确写前缀,前缀必须是跟两个连续的下划线'youtns__methodname'

例如

typedef double xsd_double;
int ns__add(xsd_double a, xsd_double b, xsd_double &result);
int ns__sub(xsd_double a, xsd_double b, xsd_double &result);
int myns__sqrt(xsd_double a, xsd_double &result);

这将在运行 soapcpp2 后生成两个 wsdl 文件: ns.wsdlmyns.wsdl

但是你是这样定义你的方法吗(一个下划线)

int ns_add(xsd_double a, xsd_double b, xsd_double &result); // wrong 

spapcpp2 不会产生任何东西。

于 2011-03-11T03:24:22.093 回答
0

您遇到的是典型的第三方在创建 Web 服务时的懒惰。我想您不会很幸运地尝试与他们推理,但是您可以手动编辑 WSDL 以删除 1.1 定义。

于 2008-11-11T23:39:11.307 回答