65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Visual C++ 2008 创建 gSoap eBay 客户端应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (19投票s)

2008年10月28日

CPOL

9分钟阅读

viewsIcon

136536

downloadIcon

2621

使用 Visual C++ 2008 实现 eBay 的 gSOAP 接口。

引言

人们可能会认为,使用简单对象访问协议 (SOAP) 在 Visual C++ 中编写客户端应用程序是一项棘手的任务。SOAP 接口调用(或多或少)是人类可读的文本,通过 HTTP(一种普遍的 Internet 传输协议)进行传输。这应该是一个简单的过程,只需将适当的数据负载组合在一起,并用格式正确的 HTTP 和 SOAP 标头进行封装,然后将消息发送出去,同时还要考虑 SSL 安全。然而,现实情况是,使用 SOAP 和 C++ 与 eBay 进行交互并不像人们想象的那么直接。

首先,尽管 C++ 是人类有史以来最广泛使用的编程语言,并在所有现代计算平台上得到普遍支持,但 eBay 选择不支持 C++。没有 C++ 的代码示例。关于 C++ 的支持查询要么被直接忽略,要么回复指向非 C++ 的示例。其次,eBay 并不严格遵守 W3C SOAP 标准。这体现在两个不同的方面,将在本文档后面介绍。最后,API 的庞大规模在智力和技术上都令人不知所措。除此之外,还有一个笨拙的开发者支持网站、糟糕的 API 文档以及模糊不清(如果不是完全不正确)的服务器错误消息。其中任何一个都会让普通开发者头疼。

本文介绍了使用 Visual C++ 中的 SOAP 与 eBay 进行交互的基本应用程序的创建过程。该应用程序将使用 Visual C++ 2008、gSOAP、OpenSSL 和 eBay API 从 eBay 服务器检索官方 eBay 时间。

第一步:使用 gSOAP

Sourceforge 下载 gSOAP。我使用了gsoap_2.7.11.tar.gz,发布于 2008 年 7 月 27 日。此文件包含预编译的 Windows 二进制文件和所需的源代码。将压缩包解压到硬盘上。假设您运行的是 Windows,解压后 gSOAP 即可运行。预编译的二进制文件可以完美运行。无需(重新)编译 gSOAP。

第二步:编译 WSDL

这是编译 WSDL 的命令行

wsdl2h -I \gsoap-2.7\gsoap\WS -f -k -o 
  eBaySvc.h http://developer.ebay.com/webservices/latest/eBaySvc.wsdl

wsdl2h.exe 是 gSoap 提供的解析器应用程序。–I 参数告诉解析器在哪里可以找到所需的 gSoap 包含文件。–f 参数告诉编译器生成 C++ 代码(而不是 C 代码)。–o 参数指定输出文件的名称。末尾的路径是 eBay SOAP API WSDL 文件的 URI。此过程将花费一些时间,因为该工具首先会下载 3.7 MB 的eBaySvc.wsdl 文件的最新版本。

如前所述,eBay 并不严格遵守 W3C SOAP 标准,因此需要使用–k 参数。-k 参数告诉 gSOAP 不要生成“mustUnderstand”限定符。摘自 W3C

SOAP mustUnderstand 全局属性可用于指示标头条目对于接收者是否是必需或可选的处理项。由 SOAP actor 属性定义标头条目的接收者。mustUnderstand 属性的值为“1”或“0”。缺少 SOAP mustUnderstand 属性在语义上等同于其带有值为“0”的出现。 […] SOAP mustUnderstand 属性允许稳健的演进。值为“1”的带有 SOAP mustUnderstand 属性标记的元素**必须**被假定为以某种方式修改其父元素或同级元素的语义。以这种方式标记元素可确保那些可能不完全理解它的人不会错误地(或可能地)忽略这种语义上的变化。

如果您向 eBay 发送“mustUnderstand”,服务器将返回错误。eBay 不理解 mustUnderstand

成功编译将生成eBaySvc.h

第三步:生成 C++ 存根

这是生成 C++ 存根的命令行

soapcpp2 -C -L -I \gsoap-2.7\gsoap\import -w -x eBaySvc.h

soapcpp2.exe 是 gSOAP 提供的 C++ 存根生成器应用程序。–C 参数告诉生成器仅生成客户端代码。(eBay 是服务器端。)–L 参数告诉生成器不要生成soapClientLib.cpp。(此文件可用于创建静态库,而不是直接将 SOAP 代码包含在项目中。创建静态库超出了本文档的范围。)–I 参数指定包含文件路径。–w 参数告诉生成器不要生成模式文件。–x 参数告诉生成器不要生成 XML 消息文件。总的来说,我试图让这个工具和wsdl2h.exe 完成最少的工作。

第四步:Open SSL

gSOAP 依赖于 Open SSL 进行 SSL 安全通信。您需要下载并编译 Open SSL 才能访问 eBay。或者,Shining Light Productions 提供 Open SSL 安装程序。我没有亲自使用过它,但它看起来可以避免编译 Open SSL 的需要。

第五步:Visual C++ 2008

为简单起见,创建一个 C++ Win32 控制台应用程序项目。接受所有默认设置。

第五步 a:在此处添加代码

将 gSOAP 生成的以下文件添加到项目中

  • eBayAPISoapBinding.nsmap
  • soapC.cpp
  • soapClient.cpp
  • soapeBayAPISoapBindingProxy.h
  • soapH.h
  • soapStub.h

将 gSOAP 目录中的以下文件添加到项目中

  • stdsoap2.cpp
  • stdsoap2.h

第五步 b:文件选项

gSOAP 从 eBay WSDL 生成的 .cpp 文件非常大。它们需要在 Visual Studio 中进行特殊处理。右键单击 Solution Explorer 中的文件soapC.cpp(仅此一个),然后从右键单击菜单中选择“Properties”。在“Configuration Properties”和“C/C++”树节点下,选择“Command Line”。在右侧面板中,输入“/bigobj”并单击“Apply”。

接下来,在“Configuration Properties”和“Precompiled Headers”下,将“Create/Use Precompiled Header”选项更改为“Not Using Precompiled Headers”。这将允许项目使用预编译的头文件,但不包括此文件。单击“Apply”。

soapClient.cpp重复此过程。

使用上述过程禁用stdsoap2.cpp的预编译头文件使用。(stdsoap2.cpp不需要“/bigobj”命令行编译器参数。)

第五步 c:项目选项

  • 右键单击项目,然后从右键单击菜单中选择“Properties”。在“Configuration Properties”、“C/C++”和“General”下,将 gSOAP 和 Open SSL 的包含路径添加进去。单击“Apply”。
  • 在“Configuration Properties”、“C/C++”和“Preprocessor”下,将“WITH_OPENSSL”(启用 gSOAP 中的 SSL)和“DEBUG”(启用日志记录)添加到“Preprocessor Definitions”列表中。单击“Apply”。
  • 在“Configuration Properties”、“Linker”和“General”下,将 Open SSL 二进制目录(编译后的 lib 文件所在位置)的路径添加到“Additional Library Directories”。单击“Apply”。
  • 在“Configuration Properties”、“Linker”和“Input”下,将“libeay32.lib”和“ssleay32.lib”添加到“Additional Dependencies”。这些是 Open SSL 库。单击“Apply”。

第五步 d:编写代码时间!(好吧,不是真的。)

打开控制台应用程序 C++ 文件。在 stdafx.h include 之后,在文件顶部添加三个 #include

#include "soapeBayAPISoapBindingProxy.h"
#include "eBayAPISoapBinding.nsmap"
#include "stdsoap2.h" 

第五步 e:测试构建

现在是时候测试到目前为止是否一切都已正确完成。构建解决方案。此时,解决方案应该能够构建,没有 0 个错误和 0 个警告。如果没有,则意味着您错过了上面的某个步骤。

第五步 f:与 eBay 互动

使用您喜欢的网络浏览器,访问 http://developer.ebay.com。您需要

  1. 建立一个开发者账户。
  2. 生成一组沙盒密钥(AppIdDevIdCertId – 也称为 AuthCert)。
  3. 在沙盒中注册一个用户账户。
  4. 获取用户令牌。
  5. 使用 API 测试工具验证您是否已完成以上所有步骤。

完成上述操作的确切步骤留给读者作为练习。请自行尝试体验 eBay 的笨拙之处。

第五步 g:SOAP 配置

尽管 gSOAP 支持 SSL,但 SSL 并非开箱即用。要配置 SSL,您需要一个包含受信任证书颁发机构的公用证书的文件。gSOAP 提供了此文件。您可以从 此处下载。

获得此文件后,还需要进行代码配置。打开soapeBayAPISoapBindingProxy.h。在 soap_new() 调用之后,添加以下代码

soap_ssl_init();
if (soap_ssl_client_context(soap, SOAP_SSL_DEFAULT, NULL, NULL, 
    "C:\\Path\\To\\Certs\\File\\cacerts.pem", NULL, NULL ))
{
     soap_print_fault(soap, stderr);
}

请确保更新解压后的cacerts.pem文件的路径以匹配您的系统。

警告:以上代码已添加到工具生成的文件中。如果重新运行该工具,此更改将被覆盖。您需要重新添加此代码。

第五步 g:编写代码时间!(这次是真的!)

我们终于可以做一些有意义的事情了。首先,在应用程序的 main() 中输入上面第 5f 步中获得的所有值。例如:

std::string sAppId("");
std::string sDevId("");
std::string sCertId("");
std::string sUserToken(""); 

接下来,声明 eBay 代理对象并配置 SOAP 标头

eBayAPISoapBinding eBayProxy;
eBayProxy.soap->header = new SOAP_ENV__Header;
eBayProxy.soap->header->ns1__RequesterCredentials = new ns1__CustomSecurityHeaderType;
eBayProxy.soap->header->ns1__RequesterCredentials->eBayAuthToken = &sUserToken;
eBayProxy.soap->header->ns1__RequesterCredentials->Credentials = new ns1__UserIdPasswordType;
eBayProxy.soap->header->ns1__RequesterCredentials->Credentials->AppId = &sAppId;
eBayProxy.soap->header->ns1__RequesterCredentials->Credentials->DevId = &sDevId;
eBayProxy.soap->header->ns1__RequesterCredentials->Credentials->AuthCert = &sAuthCert; 

准备请求和响应对象

ns1__GeteBayOfficialTimeRequestType req;
ns1__GeteBayOfficialTimeResponseType resp;

std::string sVersion("577");
req.Version = &sVersion;

req.DetailLevel.push_back(ns1__DetailLevelCodeType__ReturnAll);

std::string sLanguage("en_US");
req.ErrorLanguage = & sLanguage;

以下是 eBay 不遵守 W3C SOAP 标准的第二个方面。使用 SOAP,参数应包含在通过 HTTP 发布的 POST 数据负载中。然而,eBay 要求将一些数据负载参数重复到 SOAP 调用发布的 URL 上。(我不知道为什么需要这种重复。尝试从 eBay 获取答案一直没有得到回复。)

因此,下一步是将应用程序 ID 和其他参数“黑入”到端点 URL 中。

eBayProxy.endpoint = "https://api.sandbox.ebay.com/wsapi?callname=GeteBayOfficialTime&
   siteid=0&appid=<your>&version=577&routing=default";

最后,您就可以进行调用了!

int err = eBayProxy.__ns1__GeteBayOfficialTime( &req, &resp );
if( err == SOAP_OK )
{
    // do something with the response
}
else
{
    // do something in response to the error
}

第五步 h:再次构建

编译结果应该没有 0 个错误,0 个警告。生活真美好!

第五步 i:配置依赖项

示例应用程序需要将 Open SSL DLL libeay32.dllssleay32.dll 复制到项目目录。

第五步 j:快跑,福雷斯特!快跑!

按 F5 在调试器中运行应用程序。您应该会看到一个命令提示符窗口打开,短暂延迟后,该命令提示符窗口将关闭。检查您的项目目录,寻找三个文件:TEST.LOGSENT.LOGRECV.LOG。最大的文件TEST.LOG 将包含 gSOAP 的跟踪输出。在我的测试中,这个文件并没有什么用,但我不是 gSOAP 的开发者。SENT.LOG 包含发送到 eBay 服务器的内容,包括目标、操作、HTTP 标头和 XML 数据负载。RECV.LOG 包含从 eBay 服务器收到的内容。这些文件已包含在示例项目中供您查看。

请注意,从 eBay 收到的 XML 包含以下格式的时间戳

<timestamp>2008-08-20T18:06:24.565Z<timestamp />

然而,gSOAP 响应对象将为程序员提供一个 4 字节的 time_t 值,它已经解析了 XML 并将文本值转换为 C++ 友好的二进制数据。

就是这样。恭喜!您所做的一切都是为了这四个字节。

常见问题解答

  • Q1:为什么选择 Visual Studio 2008?
  • A1:实际上,这个问题包含两个问题
    • Q1.1:为什么选择 Visual C++ 而不是其他 C++?
    • A1.1:我的唯一回答是,我当时工作的客户要求在应用程序中使用 Visual C++,所以我用它来创建示例应用程序和文章。使用 Visual C++ 以外的 C++ 版本来实现留给读者作为练习。
    • Q1.2:为什么选择 Visual C++ 2008 而不是早期版本?
    • A1.2:2008 年之前的 Visual C++ 版本(VC++ 编译器版本 9.0)无法编译从 eBay WDSL 文件生成的源文件。源文件非常大,会压垮 VS 2003 和 VS 2005 中的编译器。VC++ 2008 编译器支持/bigobj 标志,这是早期版本所没有的。

历史

  • 2008 年 10 月 29 日 - 添加了常见问题解答和第一个问题。
© . All rights reserved.