大名鼎鼎的gSOAP Toolkit 这里就不多做介绍了,此次的WebService访问即是借助此工具开发的,获取最新版本可以上sourceforge获取,此处是下载地址http://sourceforge.net/projects/gsoap2/,这里使用的是2.8版本。首先通过WSDL文档生成C++头文件
WSDL (Web Services Description Language,Web服务描述语言)是一种XML Application,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务访问点对包含面向文档信息或面向过程调用的服务进行访问(类似远程过程调用)。WSDL首先对访问的操作和访问时使用的请求/响应消息进行抽象描述,然后将其绑定到具体的传输协议和消息格式上以最终定义具体部署的服务访问点。相关的具体部署的服务访问点通过组合就成为抽象的Web服务。
通过WSDL生成访问接口:(http://10.130.40.220:9081/dcmsWebservice/webservice/unifiedMessage?wsdl为此次调试WebService接口)设定c/c++工程名称为TestWebService(Console程序,其他应用程序类型也可),在该文件夹下面建立TestWebService.h文件。
启动cmd,进入到下载下来的gSoap包的解压路径,然后在解压出来的根目录下找到\gsoap\bin\win32目录,调用wsdl2h.exe程序生成TestWebService.h头文件接口定义。
wsdl2h -s –o x:/xxx/TestWebService.hhttp://10.130.40.220:9081/dcmsWebservice/webservice/unifiedMessage?wsdl
这里提供一下该目录下两个可执行文件的常用选项:
wsdl2h常用选项
- -o 文件名,指定输出头文件
- -n 名空间前缀 代替默认的ns
- -c 产生纯C代码,否则是C++代码
- -s 不要使用STL代码
- -t文件名,指定type map文件,默认为typemap.dat
- -e 禁止为enum成员加上名空间前缀
soapcpp2常用选项
- -C 仅生成客户端代码
- -S 仅生成服务器端代码
- -L 不要产生soapClientLib.c和soapServerLib.c文件
- -c 产生纯C代码,否则是C++代码(与头文件有关)
- -I 指定import路径(见上文)
- -x 不要产生XML示例文件
- -i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。
然后解析TestWebService.h文件,生成存根程序(若需要纯C语言可以使用-c,而非-C,具体可参看常用选项):
soapcpp2 –C x:/xxx/TestWebService.h
执行成功之后在当前路径下生成下列文件:
如果在执行该步骤时如果看到soapcpp2提示:”Critical error: #import: Cannot open file "stlvector.h" forreading. “, 那是因为我们的头文件使用了STL(wsdl2h 没用-s选项 ),这时要使用-I选项指定gSOAP的 import文件路径,这个路径是"$gsoap\gsoap\import ",$gsoap为解压目录:
soapcpp2 hello.h -I xx\gsoap\import
使用生成的头文件调试WebService
建立以TestWebService为名称的console工程,将生成的soapC.cpp、soapH.h、soapStub.h、soapunifiedMessageSoapBindingProxy.h、soapClient.cpp、unifiedMessageSoapBinding.nsmap拷贝到工程目录并加入到工程中;
然后将在gsoap解压目录下的stdsoap2.h,stdsoap2.cpp拷贝到工程目录并加入到工程中。
需要注意的是:
1、stdsoap2.cpp、soapC.cpp、soapServiceSoapProxy.cpp 不需要预编译
2、常见错误示例: 如error C1010 ,一般是预编译头文件的问题,在主函数中需要选预编译,添加 StdAfx.h;如error LNK2001,一般是在网络编程中需要WSOCK32.lib,添加上即可。
此时工程结构如下:
新建TestWebService.cpp,cpp结构如下,包含main函数整体代码:
- #include "soapH.h"
- #include "unifiedMessageSoapBinding.nsmap"
- #include "soapStub.h"
- #include "stdsoap2.h"
- #include "md5.h"
- #include
- #include
- using namespace std;
- std::string UTF8ToGB(const char* str);
- int main()
- {
- struct ns1__doServiceResponse loginResponse;
- string m_strRespContent = "";
- struct soap clientSOAP;
- // 产生MD5摘要
- char buf[64] = {0};
- char digest[16] = {0};
- char printable[64] = {0};
- strcpy(buf, "1001");
- md5_state_t state;
- md5_init(&state);
- md5_append(&state, (const md5_byte_t *)buf, strlen(buf));
- md5_finish(&state, (md5_byte_t *)digest);
- md5_digest_printable((md5_byte_t *)digest, printable, sizeof(printable));
- soap_init(&clientSOAP);
- if(soap_call_ns1__doService(&clientSOAP, NULL,
- NULL, "3000", "1001", "1001", "ucdsAddress", loginResponse._return_) == SOAP_OK)
- {
- m_strRespContent = UTF8ToGB(loginResponse._return_);
- printf(m_strRespContent.c_str());
- }
- else
- {
- printf("Error\n");
- }
- soap_destroy(&clientSOAP);
- soap_end(&clientSOAP);
- soap_done(&clientSOAP);
- while(1);
- return 0;
- }
其中soap_call_ns1__doService即为此WebService的功能接口,可以在生成的soapClient.cpp中查看此接口,到这里对此WebService的基础调用就全部完成了。