通过gsoap使用webservice

一. 按照原来预研究的结果,使用gsoap的方法如下:

  1. wsdl2h.exe -o weather.h http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsd生成
    weather.h文件。
  2. soapcpp2.exe -C weather.h -I E:\temp\gsoap-2.8\gsoap\import(E:\temp\gsoap-2.8\gsoap\import是我本地的路径),这样可以生成C++文件(soapClient.cpp, soapH.h, soapStub.h, WeatherWebServiceSoap.nsmap),然后还需要stdsoap2.cpp和stdsoap2.h 2个文件,编译的时候把这些文件加到工程中。调用的方法会在soapStub.h 头文件中产生。
    参照了以后几个wiki:

c++ 通过 gsoap实现 webservice(附带天气实现的例子)
C++访问WebService(gSoap方式和com组件方式)
C++访问WebService(gSoap方式和com组件方式)

二. 以上步骤我本地测试网上公开的天气接口,证明是可用的,后面第三方接口提供了,我安装以上方法去使用第三方的webservice接口,发现一些问题:

  1. 编译的时候出现找不到"stdafx.h"
    解决:通过在响应的.cpp中最开始添加#include "stdafx.h",修复该编译错误
  2. 编译时遇到 stdsoap2.obj : error LNK2001: 无法解析的外部符号_namespaces
    解决: stdsoap2.h,添加
      #ifndef WITH_NONAMESPACES    #define WITH_NONAMESPACES    #endif

webservice gsoap 小记

三. 以上问题解决后,又遇到一个更奇葩的问题,因为要调用第三方的二个接口,但是这二个接口确实二个不同的webservice,最开始我采取了比较普通的方法,按照gsoap的方法分别操作了二次,并且把这二次生成的文件放在了二个目录中,在工程中也是按照这样的结构添加文件,但是

  1. 编译的时候出问题"error C2374: “namespaces”: 重定义;多次初始化 gsoap",首先我就是谷歌了,按照一些搜索到的方法去做了,发现还是不行,造成这个问题的原因是因为使用多个webservice,每个.nsmap中都会定义struct Namespace,造成了重定义,怎么办呢?
    解决: 后面找了些文章,发现我们可以将多个wsdl文件统一生成为一个头文件,然后再用这个统一的头文件来生成gsoap代码则不会有冲突问题了(解救了我啊),方式是:
    wsdl2h -o file.h file1.wsdl file2.wsdl file3.wsdl‘

  2. 然后在执行【一】中的【2】,生成C++文件,这样做了后,生成了C++文件,然后加到项目中,编译,成功,小开心了一下,然后继续去测试能否获取到数据。测试的时候发现一直没有获取到数据,跟了下代码,发现返回调用公共的接口返回415错误,谷歌了下,发现是因为service端只支持 soap 1.1,而gsoap生成客户端代码默认是1.2
    解决: gsoap 的soapcpp2的参数 -1 为soap 1.1 -2为soap1.2,具体就是把【一】【2】中的soapcpp2.exe -C weather.h -I E:\temp\gsoap-2.8\gsoap\import改成soapcpp2.exe -1 -C weather.h -I E:\temp\gsoap-2.8\gsoap\import,这样就支持soap1.1了。

  3. 改了之后再测试,发现一直返回12错误,崩溃~~~,网上找了好多,也没发现是什么问题。

  4. 为了解决问题,继续找啊,发现一个blog:gSoap编写代码访问WCF服务,发现这个博主使用的是代理类的形式,我想反正我那条路已经断了,要不也参照下这个blog试一下吧,说干就干,参照这,把gsoap的操作改成一下方式了:

  5. wsdl2h.exe -v -o test.h WebService1.wsd WebService2.wsd

  6. soapcpp2.exe -1 -C -j -I E:\temp\gsoap-2.8\gsoap\import test.h
    然后把XXXProxy.cpp中的方法中的soap_endpoint的值改一下,为什么要改呢?因为默认gsoap会将所有的service的endpoint加在一起赋值给每个接口,这样就会出现类似
    soap_endpoint=
    "http://10.32.4.20:8012/QueryInterface.asmxhttp://10.32.4.20:9988/CommonService.svc";
    的形式,其实我们需要的是
    soap_endpoint = "http://10.32.4.20:8012/QueryInterface.asmx";
    所以需要手动去把有类似问题的都改一下,改好后再重新编译,OK,都没有问题,继续测试,OMG,完美,可以正常访问,心里终于舒坦了。

四. gsoap设置超时

  1. 修改gsoap自动生成的代码才能进行超时设置(我这边访问web service的代码都是gsoap工具自动生成.根据wsdl接口)
  2. 找到生成的soapwwwsdlBindingProxy.cpp文件
  3. 找到你要设置超时的那个调用服务器的方法
  4. 找到该方法代码 struct soap *soap = this;
    在该代码下添加如下三行代码(时间大小根据项目自行调整)
    soap->recv_timeout = 2;//接受 (单位是秒)
    soap->send_timeout = 2;//发送 (单位是秒)
    soap->connect_timeout = 2;//连接(单位是秒)

--以上就是这次通过gsoap使用webservice的全部过程,记录下来,方便自己以后查阅,也希望对遇到同样问题的你,有所帮助。
以上有参考一下wiki:
gsoap之client端引用多个service时命名冲突
gsoap 调用 WCF 415 错误

你可能感兴趣的:(通过gsoap使用webservice)