C++调用WebService的实现

前言:因为我们是Qt集成开发平台,一开始使用的是QGsoap。

QtSoap下载地址:https://github.com/qtproject/qt-solutions/tree/master/qtsoap

而且QtSoap 近十年也没人在维护了,但是其中有个严重的问题是不支持https的WebService的调用。

目标:gSoap实现C++调用支持ssl的WebService服务接口。因为自带的wsdl2h.exe并不支持ssl。

编译机器:windows7 x64, Visual Studio 2015

gSOAP简介

gSOAP是一个开发SOAP和XML应用(它们组成了webservice)的工具,在英文中叫toolkit。它是跨平台的,webservice的客户端和服务器端,都可以用它来辅助开发。它主要的功能(特征)如下:

  • C/C++数据绑定工具,支持XML-RPCfrom/to JSON from/to C/C++ serialization
  • 支持WSDL 1.1,2.0, SOAP 1.1, 1.2
  • 支持REST HTTP(S) 1.0/1.1 operations (GET,PUT,POST etc) for XML, JSON,etc
  • 支持MIME and MTOM 附件
  • 支持IPv4,IPv6, TCP 和UDP
  • 支持CGI,FastCGI
  • 支持嵌入到Apache,IIS中发布
  • 自带了一个Web server (multithreaded, SSL, compression)用于发布
  • 可适用于WinCE, Palm, Symbian, VxWorks, Andriod, iPhone等小设备

gsoap下载地址:http://sourceforge.net/project/showfiles.php?group_id=52781

下载开源:最近一次的Release的版本(gsoap_2.8.116.zip 2021-07-09),现在好像是最新的是2.8.117了,不过没所谓,使用方式都是一样的。

下载OpenSSL:因为gsoap2.8如果要支持ssl编译的话,需要引入OpenSSL3.0,故先去下载安装OpenSSL3.0。

下载地址:http://slproweb.com/download/Win32OpenSSL-3_0_0.exe,下载下来后,直接双击安装即可

解压文件夹后,找到gsoap-2.8\gsoap\VisualStudio2005\wsdl2h工程,直接利用vs2015打开工程,会有一个工程转换,直接确定下一步即可。

1. wsdl2h属性页 - C/C++-预处理器: 添加  WITH_OPENSSL 宏。

2. wsdl2h属性页 - VC++目录 - 包含目录:添加 D:\Program Files (x86)\OpenSSL-Win32\include

    wsdl2h属性页 - VC++目录 - 库目录:添加 D:\Program Files (x86)\OpenSSL-Win32、D:\Program Files (x86)\OpenSSL-Win32\lib

3. wsdl2h属性页 - 连接器 - 输入 : 添加 libcrypto.lib;libssl.lib

4. 将“gsoap-2.8\gsoap\plugin”目录下的 httpda.c、httpda.h、smdevp.c、smdevp.h、threads.c、threads.h拷贝到“D:\gsoap-2.8\gsoap\VisualStudio2005\wsdl2h\wsdl2h”目录下,并将此6个文件加入工程。

属性页的debug|release自己配置好了,配置的内容都是一样的。

在 gsoap-2.8\gsoap\VisualStudio2005\wsdl2h的目录下会生成debug和release两个目录,是存放生成的文件的。

wsdl2h支持ssl的编译内容结束。

下面是使用方式:

1. wsdl2h  -o WeatherWebService.h -N vis -t typemap_wchar.dat http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl

2. soapcpp2 -C -L -i -x WeatherWebService.h -I 解压的路径/gsoap-2.8/gsoap/import

上面的 typemap_wchar.dat ,是为了解决返回中文乱码问题。在原有的typemap.dat上添加了 xsd__string = | std::wstring | wchar_t*    # 注释符号为#

 那么SOAP/XML中的string将转换成std::wstring或wchar_t*,这样能更好地支持中文。

gsoap中文乱码及内存清理等问题的解决方案https://developer.aliyun.com/article/643861

生成下列文件:

 

写DEMO调用:使用的是Qt Creator,Qt 5.8.0 MSVC2015。

pro:

DEFINES += QT_DEPRECATED_WARNINGS WITH_OPENSSL
# 添加Soap库
INCLUDEPATH += $$PWD \
    "D:/Program Files (x86)/OpenSSL-Win32/include" \
    "D:/Program Files (x86)/OpenSSL-Win32/lib" \

win32:CONFIG(release, debug|release): {
    LIBS += -L$$PWD -llibssl
    LIBS += -L$$PWD -llibcrypto
}
else:win32:CONFIG(debug, debug|release): {
    LIBS += -L$$PWD -llibcrypto
    LIBS += -L$$PWD -llibssl
}

将libcrypto.lib、libssl.lib、libcrypto-3.dll、libssl-3.dll 四个文件拷贝到demo工程目录下,并将上门生成的文件添加到demo工程里。

 实现代码:

soap soap;
    soap_set_mode(&soap, SOAP_C_UTFSTRING);
    soap_ssl_init();
    soap_init(&soap);
    if ( soap_ssl_client_context(&soap, SOAP_SSL_NO_AUTHENTICATION, NULL, NULL, NULL, NULL, NULL ))
    {
       soap_print_fault(&soap, stderr);
    }

    soap.connect_timeout = 10;    /* try to connect for up to 30 seconds */
    soap.send_timeout = soap.recv_timeout = 10;    /* max I/O idle time is 10 seconds */

    portalSoapProxy service(soap);

    _ns__接口 request;
    _ns__接口Response response;
    int ret = service.接口(&request, response);
    QString error = QString::fromLocal8Bit(service.soap_fault_string());
    QString result = QString::fromWCharArray(response.GetDepartmentResult);
    ui->teditResponse->clear();
    ui->teditResponse->append(result);
    //销毁、退出
    soap_destroy(&soap);
    soap_end(&soap);
    soap_done(&soap);

结束。
以下是接触时都到先关比较好的介绍,供参考:https://www.cnblogs.com/liushui-sky/p/9723397.html

 

posted @ 2021-12-02 14:10  果园2018  阅读(1148)  评论(0编辑  收藏  举报