一:下载gsoap;
地址:http://www.cs.fsu.edu/~engelen/soap.html
一般是下载最新版本,当然有的时候版本太新也可能出问题。
二:准备好要访问的webservice地址;
类似于:http://dret.currenex.com/webservice/xml/ClientRetailService.wsdl
当然也可以把所需的wsdl文件,xsd文件下载下来使用。
三:解压gsoap;
在bin\win32目录中将会看到两个可执行文件,wsdl2h.exe,soapcpp2.exe;
四:在bin\win32进行如下操作:
1.wsdl2h -o currenex.h http://dret.currenex.com/webservice/xml/ClientRetailService.wsdl;
如果是下载到本地,可以用wsdl2h -o currenex.h ClientRetalService.wsdl;
如需查看其他命令用法:wsdl2h -help,下同;
2.soapcpp2 -j currenex.h -I../../import
这一步将会产生其他所需的文件,包括一些.h,.cpp,.nsmap文件和代理类的文件,新建工程时添加这些文件,具体有:
soap*Proxy.h,soap*Proxy.cpp,soap*Service.h,soap*Service.cpp,*.namap,*.xml,soapH.h,soapStub.h,soapC.cpp.
五:新建工程;
添加上述头文件cpp文件以及gsoap下stdsoap2.cpp,stdsoap2.h.
lib文件添加wsock32.lib;
六:如果访问的地址是https,则需要openssl进行加密;
首先参考gsoap文档19.22,http://www.cs.fsu.edu/~engelen/soap.html;
1.下载openssl
2.编译;
参考:http://software.intel.com/zh-cn/blogs/2013/12/22/windows-openssl;
当然也可以下载编译好的win版:
地址:http://slproweb.com/products/Win32OpenSSL.html;
3.修改soapdefs.h,添加#define WITH_OPENSSL,然后在预处理中添加:WITH_SOAPDEFS_H。同时将soapdefs.h放到上述所需文件同一目录下。
4.将openssl的库文件包含进来,同时添加libeay32.lib;ssleay32.lib;
5.用到代码如下:
//struct soap sp;
soap_ssl_init();
if (soap_ssl_client_context(crbp.soap,
SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE, /* SOAP_SSL_DEFAULT, SOAP_SSL_NO_AUTHENTICATION,SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE */
NULL, /* "myclient.pem","client.pem",keyfile: required only when client must authenticate to server (see SSL docs on how to obtain this file) */
NULL, /* "123456789","password",password to read the key file (not used with GNUTLS) */
"cacerts.pem", /* "cacerts.pem"cacert file to store trusted certificates (needed to verify server) */
"./", /* capath to directory with trusted certificates */
NULL /* if randfile!=NULL: use a file with random data to seed randomness */
))
{
soap_print_fault(crbp.soap, stderr);
exit(1);
}
上述代码就是用来初始化ssl,其中cacerts.pem存储了一些可信任的证书,用来和服务器验证,可以在openssl目录下找到,第六个参数就是它的目录,第三和第四个参数,目前还不太理解,似乎是客户端需要产生一个认证文件,以便和服务端相互验证,大概叫客户机验证吧,大概机制是首先客户端向服务端发起普通的tcp/ip连接,服务端响应,向客户端发送一个认证文件,这个文件究竟是用哪个CA签名的不清楚,总之客户端用cacerts.pem认证通过了,然后客户端再发送一个由自己的CA签名的证书过去,那么再然后,服务端又是怎么对这个证书进行认证的呢,又不太清楚了,看网上的例子都是服务端和客户端用的一个CA签名,这个当然是OK的啦,所以如果是仅仅进行的是客户端的开发,第三和第四个参数应该是NULL,否则是不能够被通过的。
具体如何产生自己的CA以及用这个CA对证书进行签名,参照:
官方文档:
http://www.openssl.org/docs/apps/openssl.html;
http://wiki.openssl.org/index.php/Command_Line_Utilities#s_client;
格式和协议介绍:
http://my.oschina.net/u/249511/blog/77172;
中文介绍CA安装:
http://www.cnblogs.com/E7868A/archive/2012/11/16/2772240.html;
http://rhythm-zju.blog.163.com/blog/static/310042008015115718637/;
其他:
http://gagravarr.org/writing/openssl-certs/personal.shtml;
七:大概就是以上步骤了,调试的时候当然还会遇到很多问题,比如wsdl2h 这一步的时候出现了一句extension has no base,结果soapcpp2的时候就报错,说什么产生的头文件中有标点符号错误,未定义错误,结果wsdl文件中有一个类型定义的时候有一句<extension/>就没了,将这个地方改为<extension base="xsd:string"></extension>编译就通过了。
八:体会
刚开始的时候,只想着如何快速的实现功能,结果碰到各种问题,对其中的原理什么都不懂,就按着错误去搜索,往往事倍功半,在接触一个新技术的时候,最好先去搞清楚原理,再去做就会事半功倍。