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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM