前言:因為我們是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