1 簡介
1.1 准備工作
使用gSOAP工具構建Web services應用程序或實現自動化XML數據綁定,你需要具備如下條件:
- 從http://www.genivia.com/Products/downloads.html下載gSOAP軟件包。(選擇標准版)
- C或C++編譯器
- 如想支持SSL(HTTPS)和壓縮,你還需要安裝OpenSSL、Zlib庫.這些庫適用於大多數平台,同時通常也是已經安裝好的。
- wsdl2h :WSDL/模式導入和數據映射綁定工具。(注:該工具將wsdl轉換為開發用的.h文件)
- soapcpp2 :存根/框架編譯器和代碼生成器。(注:該工具依據.h文件自動生成部分C/CPP語言代碼)
盡管gSOAP為不同平台准備了二進制格式的工具,但他們生成的代碼是等價的。這意味着生成的源代碼可以移植到其他平台並進行本地化編譯。
gSOAP引擎可以被構建成libgsoap.a和libgsoap++.a庫,后者支持SSL。參照README.txt的指示可以看到如何通過gSOAP包里的autoconf和automake構建與平台無關的庫。或者,你將引擎的源代碼stdsoap2.c(或stdsoap2.cpp)直接編譯並鏈接進你們工程里。(注:說明gSOAP提供兩種使用方式 ,一種編譯成動態鏈接庫,或者直接將源代碼編譯進工程)
1.2 快速開始:開發一個Web Service客戶端應用程序
wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
使用wsdl2h生成的服務定義頭文件同樣包含如何調用服務的信息。
在這個例子中,我們開發一個基於C++的計算器服務。默認情況下,gSOAP假定我們使用C++的STL。如不想使用STL,使用選項-s:
wsdl2h -s -o calc.h http://www.genivia.com/calc.wsdl
到現在為止,我們還沒有生成C/C++的存根。為了生成它,我們使用soapcpp2編譯器:
soapcpp2 -i -C -Iimport calc.h
選項-i指示我們希望得到C++代理和包含客戶端(服務端)代碼的對象。-C指示只生成客戶端對象(默認情況下,gsoapcpp2同時生成客戶端和服務端對象)。選項-I指示需要從import目錄引入stl vector.h文件,以支持STL容器序列化,import目錄也在gSOAP包中。
假定我們開發一個C++計算器客戶端:
wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
soapcpp2 -i -C calc.h
(注:事實上執行第二行命令需要指定-I路徑,如下所示:其中紅色的文件是該步驟生成的)
./soapcpp2 -i -C -I/home/infor/renhc/gsoap/gsoap_2.8.5/gsoap-2.8/gsoap/import calc.h
[infor@s123 linux386]$ ls -ltr
total 3376
-rwxr-xr-x 1 infor app 2383149 Dec 6 11:46 wsdl2h
-rwxr-xr-x 1 infor app 818123 Dec 6 11:46 soapcpp2
-rw-r--r-- 1 infor app 5249 Dec 6 13:53 calc.wsdl
-rw-r--r-- 1 infor app 24316 Dec 6 14:42 calc.h-rw-r--r-- 1 infor app 7101 Dec 6 14:44 soapStub.h
-rw-r--r-- 1 infor app 34463 Dec 6 14:44 soapH.h -rw-r--r-- 1 infor app 95689 Dec 6 14:44 soapC.cpp -rw-r--r-- 1 infor app 3573 Dec 6 14:44 soapcalcProxy.h -rw-r--r-- 1 infor app 12319 Dec 6 14:44 soapcalcProxy.cpp -rw-r--r-- 1 infor app 490 Dec 6 14:44 calc.sub.res.xml -rw-r--r-- 1 infor app 478 Dec 6 14:44 calc.sub.req.xml -rw-r--r-- 1 infor app 490 Dec 6 14:44 calc.pow.res.xml -rw-r--r-- 1 infor app 478 Dec 6 14:44 calc.pow.req.xml -rw-r--r-- 1 infor app 521 Dec 6 14:44 calc.nsmap -rw-r--r-- 1 infor app 490 Dec 6 14:44 calc.mul.res.xml -rw-r--r-- 1 infor app 478 Dec 6 14:44 calc.mul.req.xml -rw-r--r-- 1 infor app 490 Dec 6 14:44 calc.div.res.xml -rw-r--r-- 1 infor app 478 Dec 6 14:44 calc.div.req.xml -rw-r--r-- 1 infor app 490 Dec 6 14:44 calc.add.res.xml -rw-r--r-- 1 infor app 478 Dec 6 14:44 calc.add.req.xml
我們使用生成的soapcalcProxy類和XML命名空間映射表calc.nsmap來訪問Web服務。該soapcalcProxy類是調用服務的一個代理。
#include "soapcalcProxy.h" #include "calc.nsmap" main() { calcProxy service; double result; if (service.add(1.0, 2.0, result) == SOAP_OK) std::cout << "The sum of 1.0 and 2.0 is " << result << std::endl; else service.soap_stream_fault(std::cerr); }
接下來我們編譯並鏈接生成的soapC.cpp和soapcalcProxy.cpp,以及動態鏈接庫-lgsoap++(如果你沒有安裝該庫,可以將stdsoap2.cpp引入到你的代碼)。(注:上面就構建完了基於C++的客戶端)
1.3 快速開始:開發Web 服務
// File: currentTime.h //gsoap ns service name: currentTime //gsoap ns service namespace: urn:currentTime //gsoap ns service location: http://www.yourdomain.com/currentTime.cgi int ns__currentTime(time_t& response);
// File: currentTime.cpp #include "soapH.h" // include the generated declarations #include "currentTime.nsmap" // include the XML namespace mappings int main() { // create soap context and serve one CGI-based request: return soap_serve(soap_new()); } int ns__currentTime(struct soap *soap, time_t& response) { response = time(0); return SOAP_OK; }
soapcpp2 -S currentTime.h
接着編譯得到CGI二進制程序:
c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp stdsoap2.cpp
CGI可以方便的通過標准I/O交換信息。因此,我們使用自動生成的請求樣例代碼來測試:
./currentTime.cgi < currentTime.currentTime.req.xml
這樣,得到的返回也是SOAP XML。
另外還有一個更優雅的C++服務端實現:使用soapcpp2的-i(或-j)選項生成C++的客戶端和服務端的服務類,使用這個類同時可以構建客戶端也可以構建服務端。使用這個選項就不需要 soapClient.cpp和 soapServer.cpp了,因為我們有了客戶端和服務端的類實現:
soapcpp2 -i -S currentTime.h
// File: currentTime.cpp #include "soapcurrentTimeService.h" // include the proxy declarations #include "currentTime.nsmap" // include the XML namespace mappings int main() { // create server and serve one CGI-based request: currentTimeService server; return server.serve(); } int currentTimeService::currentTime(time_t& response) { response = time(0); return SOAP_OK; }
編譯:
c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapcurrentTimeService.cpp -lgsoap++
接着安裝CGI二進制文件。安裝方法請查閱Web服務文檔。
如果想在8080端口上以迭代方式運行服務,可以使用:
return currentTimeService.run(8080);
