一.开发环境准备
1.从gSoap官方网站http://gsoap2.sourceforge.net下载gSoap工具包。
本例下载的是2.8.15的版本。
2.根据说明文档(README)配置安装gSoap工具包。
说明: 一般下载的gSoap工具包中已经包含了生成Web Service客户端需要用到的两个工具(可执行文件):wsdl2h.exe和soapcpp2.exe,一般win32版本在gsoap\bin\win32下。只是默认情况下,wsdl2h并不支持SSL,即无法访问HTTPS站点,且这两个工具的版本一般也要低于所在gSoap工具包的版本。
所以如果想要支持SSL等更多功能,就需要自己重新配置编译该gSoap工具包,以生成新的sdl2h和soapcpp2。
反之,如果下载的gSoap工具包中自带的wsdl2h和soapcpp2已经满足了你的需求,就可以不必再配置编译gSoap工具包,而是直接使用工具包自带的wsdl2h和soapcpp2。
二.wsdl2h和soapcpp2工具工具的使用
1. 通过WSDL文件生成头文件(.h)
用法:
Wsdl2h [-o 头文件名] [WSDL文件名或URL]
wsdl2h 常用选项
-o 文件名,指定输出头文件
-n 名空间前缀 代替默认的ns
-c 产生纯C代码,否则是C++代码
-s 不要使用STL代码
-t 文件名,指定type map文件,默认为typemap.dat
-e 禁止为enum成员加上名空间前缀
该步的目的:使用gSoap工具wsdl2h,根据WSDL生成一个C/C++语法结构的头文件。实现WSDL文件到.h文件的数据映射。
示例(其中的头文件名称和wsdl文件链接按实际情况填入):
wsdl2h -s -o mapp.h http://****/mapp.wsdl
该语句将得到一个头文件:mapp.h
2. 通过头文件(如:mapp.h)生成所需要的c/cpp 文件
用法:
soapcpp2 [头文件]
soapcpp2 常用选项
-C 仅生成客户端代码
-S 仅生成服务器端代码
-L 不要产生soapClientLib.c和soapServerLib.c文件
-c 产生纯C代码,否则是C++代码(与头文件有关)
-I 指定import路径(见上文)
-x 不要产生XML示例文件
-i 生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)
该步目的:使用gSoap的预编译器soapcpp2生成相应的底层通信代码。
示例(以下命令只生成客户端使用代码):
soapcpp2 -i -x -C -L mapp.h
提示:执行时如果看到soapcpp2提示:Critical error: #import: Cannot open file "stlvector.h" for reading.等 那是因为我们的头文件使用了STL(wsdl2h 没用-s选项),这时要使用-I选项指定gSOAP的 import文件路径,这个路径是"$gsoap\gsoap\import":
如下(import路径按用户系统实际路径指定):
soapcpp2 -i -x -C -L mapp.h -I D:\gsoap-2.8\gsoap\import
上述命令执行结果生成如下文件:
soapH.h soapStub.h soapC.cpp
MappBinding.nsmap
soapMappBindingProxy.h
soapMappBindingProxy.cpp
上述文件具体含义见【附1】
三.在vc中使用gsoap编写soap客户端示例
1. 在vc中创建一个win32项目 (mfc项目通用)。将soapcpp2 生成的所有文件加入到工程下。
2. 将gsoap目录下的 stdsoap2.cpp、stdsoap2.h 两个文件引入工程中(编译需要)。
3. 客户端实现代码如下:
#include <iostream>
#include "soapMappBindingProxy.h"
#include "MappBinding.nsmap"
int main(int argc, char** argv)
{
MappBindingProxy Proxy;
_ns1__doCicRequest cicReq;
_ns1__doCicRequestResponse cicRes;
cicReq.msg = new char[1024];
memset(cicReq.msg,0,sizeof(cicReq.msg));
strcpy(cicReq.msg,"<?xml version=\"1.0\" encoding=\"GBK\"?><INSUREQ>\
<MSG>soap client message.</MSG></INSUREQ>");
std::cout << "请求数据:" << cicReq.msg << std::endl;
Proxy.doCicRequest(&cicReq,&cicRes);
std::cout << "接收数据:" << cicRes.return_ << std::endl;
return 0;
}
4. 编译注意事项:
1). 在vc中开发,需要对引入的3个cpp文件进行设置 不使用预编译头,设置方式如下: 工程 -> 设置 -> 选择cpp文件 -> 预编译头 -> 选择不使用
2). 在程序中如不使用默认的webService地址,调用xxxxxProxy类的指定构造函数。
MappBindingProxy Proxy(surl);
3). 字符编码设置,详情见【附2】
附1: 文件含义解析
1). MappBinding.nsmap
该文件的作用:An XML-to-C/C++ namespace mapping table,即WSDL文件与生成的客户端代码框架的一个名字空间的映射表。
2). soapStub.h
该文件就是直接由wsdl2生成的头文件转化而来,它详细定义了WSDL所描述的各项服务和数据结构。它是soap的存根文件,定义了由wsdl2生成的头文件里对应的远程调用模型(RPC)。
3). soapMappBindingProxy.h 和soapMappBindingProxy.cpp
这两个文件是客户端代码的一个简单封装,它封装了底层通信,并向外提供一个很简单的界面,该界面展示了用户能够使用的所有服务(由WSDL所描述)。
4). soapH.h和soapC.cpp
这个两个文件是soap的序列和反序列化代码。
附2 :设置字符编码
在利用gSoap编写Web Service客户端和服务器端的程序时,需要设置其编码方式。接口为:soapsetmode,其实它是就是一个宏:
#define soap_set_mode(soap, n) ((soap)->imode |= (n), (soap)->omode |= (n))
如果要设置为UTF-8 ,可以如下调用:
soap_set_mode(&soap, SOAP_C_UTFSTRING);
详细信息可参考该宏所在文件:stdsoap2.h