利用C++调用天气webservice-gSOAP方法

利用C++调用天气webservice-gSOAP方法

首先需要下载一个gSOAP工具包 下载路径为:https://sourceforge.NET/projects/gsoap2/

至于有关于gSOAP的一些用法和包含的文件的说明可从官网查看:http://www.genivia.com/dev.html。

下载和使用gSOAP生成一些库文件提供给C++工程使用:

  1. 解压gsoap文件夹,此处解压的是gsoap-2.8文件夹,放在E盘
  2. 打开E:\gsoap-2.8\gsoap\bin\win32文件夹
  3. 创建一个文件名为wsmap.dat 以文本形式写入  xsd__string = | std::wstring | wchar_t*   ,此文件用来将SOAP/XML中的string转换成std::wstrin或wchar_t*,这样能更好地支持中文
  4. cmd命令行方式到 cd E:\gsoap-2.8\gsoap\bin\win32文件夹,调用wdsl2h.exe文件生成头文件接口定义,命令为 wdsl2h -o WebService.h -n WS -t wsmap.dat http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL

         WebService.h为头文件名称,可自选

        http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL 为需要访问的webservice的WSDL文件地址
 

  •     -o 文件名,指定输出头文件
  •     -n 名空间前缀 代替默认的ns
  •     -c 产生纯C代码,否则是C++代码
  •     -s 不要使用STL代码
  •     -t 文件名,指定type map文件,默认为typemap.dat
  •     -e 禁止为enum成员加上名空间前缀

         5.输入soapcpp2 -C WebService.h -i -L -I E:\gsoap-2.8\gsoap\import

  •     -C 仅生成客户端代码
  •     -S 仅生成服务器端代码
  •     -L 不要产生soapClientLib.c和soapServerLib.c文件
  •     -c 产生纯C代码,否则是C++代码(与头文件有关)
  •     -I 指定import路径(此项是必要的,因前面为指定-s)
  •     -x 不要产生XML示例文件
  •     -i生成C++包装,客户端为xxxxProxy.h(.cpp),服务器端为xxxxService.h(.cpp)。

        6.将生成的soapH.h、soapStub.h、soapWeatherWebServiceSoapProxy.h、WeatherWebService.h、soapWeatherWebServiceSoapProxy.cpp、soapC.cpp、WeatherWebServiceSoap.nsmap  E:\gsoap-2.8\gsoap文件夹下的stdsoap2.h、stdsoap2.cpp拷贝到要使用的工程目录下

下面贴入代码段:

首先声明阶段include 要载入的头文件和命名空间,要引入.nsmap文件是因为此为要使用的webservice命名空间

  1. <pre name="code" class="cpp">#include <iostream>  
  2. #include <vector>  
  3. #include <string>  
  4. #include <locale>   
  5.   
  6. //载入webservice的头文件和命名空间  
  7. #include "soapWeatherWebServiceSoapProxy.h"     
  8. #include "WeatherWebServiceSoap.nsmap"  

using namespace std;

 

上面使用了vector头文件是为了能够输出信息,天气webservice中所有返回数据都是vector类型下面我们会讲到

接下来我们初始化webservice

  1.        //初始化webservice对象  
  2. WeatherWebServiceSoapProxy proxy("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx");  
  3.   
  4. //城市名称,可为空,为空则显示所有的城市对应的编码  
  5. string City("");  
  6. int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)City.c_str(), -1, NULL, 0);  
  7. wchar_t * wszutf8 = new wchar_t[len + 1];  
  8. memset(wszutf8, 0, len * 2 + 2);  
  9. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)City.c_str(), -1, (LPWSTR)wszutf8, len);  
  10.   
  11.   
  12. //设置编码格式  
  13. //soap_set_mode(&proxy, SOAP_C_MBSTRING);  
  14.   
  15.          


初始化的时候使用webservice的访问地址,不需要添加WSDL文件后缀。

初始化getSupportCity对象,getSupport对象的属性可从http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?op=getSupportCity 中查看为

查询本天气预报Web Services支持的国内外城市或地区信息

输入参数:byProvinceName = 指定的洲或国内的省份,若为ALL或空则表示返回全部城市;返回数据:一个一维字符串数组 String(),结构为:城市名称(城市代码)。

然后我们创建一个返回Support City信息的类对象

  1. <pre name="code" class="cpp">        //初始化getSupportCity对象  
  2.        _WS1__getSupportCity weatherCity;  
  3.     weatherCity.soap = &proxy;  
  4.     weatherCity.byProvinceName = wszutf8;  


_WS1__getSupportCityResponse response; proxy.getSupportCity(&weatherCity, response);wcout.imbue(locale("chs"));for (int i = 0; i < response.getSupportCityResult->string.size(); i++) wcout << response.getSupportCityResult->string[i] << endl;

 

在这个里面可以看到我们输出是使用的是wcout 而不是 cout 因为 这个是getSupportCityResult这个成员属性是一个自定义的属性,用来保存的数据都是以wchar形式保存的

至于为什么会是wchar是因为原来我们使用的那一段文字 xsd__string = | std::wstring | wchar_t* 这将string类型转换为wstring 或 wchar。这样可以保证中文文字的合理显示,否则会出现乱码。

出现乱码的原因:HTML和XML中通用的编码格式是UTF-8,而代码一般是使用Unicode。但是如果webservice是使用C++编写的,则不需要wchar也可以使用。而使用的如果是C#、Java之类的编写的webservice则不使用wchar进行传参就会造成乱码。

这里需要说明的是一般的默认显示是_ns1_getSupportCity,而我显示的是_WS1_getSupportCity原因是因为   wdsl2h -o WebService.h -n WS -t wsmap.dat http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL这条命令中我输出了一个-n WS将名称前缀换掉了

从_WS1_getSupportCityResponse的定义知道getSupportCityResult这个成员变量是自定义的一个属性

soapStub.h

  1. /* WeatherWebService.h:170 */  
  2. #ifndef SOAP_TYPE__WS1__getSupportCityResponse  
  3. #define SOAP_TYPE__WS1__getSupportCityResponse (14)  
  4. /* WS1:getSupportCityResponse complex type: */  
  5. class SOAP_CMAC _WS1__getSupportCityResponse  
  6. {  
  7. public:  
  8.     WS1__ArrayOfString *getSupportCityResult;   /* SOAP 1.2 RPC return element (when namespace qualified) */    /* optional element of XSD type WS1:ArrayOfString */  
  9.     struct soap *soap;  /* transient (not serialized) */  
  10. public:  
  11.     /// Return the unique type ID value SOAP_TYPE__WS1__getSupportCityResponse (14)  
  12.     virtual int soap_type(void) const { return 14; }  
  13.     /// Set object's data members to default values  
  14.     virtual void soap_default(struct soap*);  
  15.     /// Serialize object to prepare for SOAP 1.1/1.2 encoded output (or with SOAP_XML_GRAPH) by analyzing its (cyclic) structures  
  16.     virtual void soap_serialize(struct soap*) const;  
  17.     /// Output object in XML, compliant with SOAP 1.1 encoding style, return error code or SOAP_OK  
  18.     virtual int soap_put(struct soap*, const char *tag, const char *type) const;  
  19.     /// Output object in XML, with tag and optional id attribute and xsi:type, return error code or SOAP_OK  
  20.     virtual int soap_out(struct soap*, const char *tag, int id, const char *type) const;  
  21.     /// Get object from XML, compliant with SOAP 1.1 encoding style, return pointer to object or NULL on error  
  22.     virtual void *soap_get(struct soap*, const char *tag, const char *type);  
  23.     /// Get object from XML, with matching tag and type (NULL matches any tag and type), return pointer to object or NULL on error  
  24.     virtual void *soap_in(struct soap*, const char *tag, const char *type);  
  25.     /// Return a new object of type _WS1__getSupportCityResponse, default initialized and not managed by a soap context  
  26.     virtual _WS1__getSupportCityResponse *soap_alloc(void) const { return SOAP_NEW(_WS1__getSupportCityResponse); }  
  27.              _WS1__getSupportCityResponse() { _WS1__getSupportCityResponse::soap_default(NULL); }  
  28.     virtual ~_WS1__getSupportCityResponse() { }  
  29.     friend _WS1__getSupportCityResponse *soap_instantiate__WS1__getSupportCityResponse(struct soap*, int, const char*, const char*, size_t*);  
  30. };  
  31. #endif  

此自定义属性为WS1_ArrayOfString 类型,此类型的定义可以看出为什么要使用wchar类型

  1. /* WeatherWebService.h:164 */  
  2. #ifndef SOAP_TYPE_WS1__ArrayOfString  
  3. #define SOAP_TYPE_WS1__ArrayOfString (12)  
  4. /* WS1:ArrayOfString complex type: */  
  5. class SOAP_CMAC WS1__ArrayOfString  
  6. {  
  7. public:  
  8.     std::vector<std::wstring> string; /* optional element of XSD type xsd:string */  
  9.     struct soap *soap;  /* transient (not serialized) */  
  10. public:  
  11.     /// Return the unique type ID value SOAP_TYPE_WS1__ArrayOfString (12)  
  12.     virtual int soap_type(void) const { return 12; }  
  13.     /// Set object's data members to default values  
  14.     virtual void soap_default(struct soap*);  
  15.     /// Serialize object to prepare for SOAP 1.1/1.2 encoded output (or with SOAP_XML_GRAPH) by analyzing its (cyclic) structures  
  16.     virtual void soap_serialize(struct soap*) const;  
  17.     /// Output object in XML, compliant with SOAP 1.1 encoding style, return error code or SOAP_OK  
  18.     virtual int soap_put(struct soap*, const char *tag, const char *type) const;  
  19.     /// Output object in XML, with tag and optional id attribute and xsi:type, return error code or SOAP_OK  
  20.     virtual int soap_out(struct soap*, const char *tag, int id, const char *type) const;  
  21.     /// Get object from XML, compliant with SOAP 1.1 encoding style, return pointer to object or NULL on error  
  22.     virtual void *soap_get(struct soap*, const char *tag, const char *type);  
  23.     /// Get object from XML, with matching tag and type (NULL matches any tag and type), return pointer to object or NULL on error  
  24.     virtual void *soap_in(struct soap*, const char *tag, const char *type);  
  25.     /// Return a new object of type WS1__ArrayOfString, default initialized and not managed by a soap context  
  26.     virtual WS1__ArrayOfString *soap_alloc(void) const { return SOAP_NEW(WS1__ArrayOfString); }  
  27.              WS1__ArrayOfString() { WS1__ArrayOfString::soap_default(NULL); }  
  28.     virtual ~WS1__ArrayOfString() { }  
  29.     friend WS1__ArrayOfString *soap_instantiate_WS1__ArrayOfString(struct soap*, int, const char*, const char*, size_t*);  
  30. };  
  31. #endif  

定义的string其实是一个vector<wstring>类型的,这也是为什么我要使用vector头文件和 char与wchar转换的原因。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值