在C++中使用soap toolkit訪問Web Service,一般要用到以下幾個接口:
- ISoapConnector
- ISoapSerializer
- ISoapReader
這三個接口顧名思義。ISoapConnector實現(xiàn)了在對象之間發(fā)送和接收SOAP消息的傳輸協(xié)議;ISoapSerializer用于序列化(串行化),創(chuàng)建、封裝SOAP消息;ISoapReader用于讀取SOAP消息,將SOAP消息解析為一個DOM模型,并提供了一系列操作該DOM模型的方法。
使用Soap Toolkit的應用程序,需要引入動態(tài)庫MSSOAP1.dll(當前最新版本是Soap Toolkit3.0:MSSOAP3.dl),同時還需要msxml3.dll用于解析DOM和XML。在程序的開頭可以這樣來引入相關的文庫和名稱空間:
#import "msxml3.dll"
using namespace MSXML2;
#import "D:/Program Files/Common Files/MSSoap/Binaries/MSSOAP1.dll" /
exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", "_ULARGE_INTEGER",
"tagSTATSTG", "_FILETIME")
using namespace MSSOAPLib;
string LoginTest(string strIP, int nPort);
下面的代碼說明了如何來訪問該Web服務。
ISoapConnectorPtr Connector;
ISoapSerializerPtr Serializer;
ISoapReaderPtr Reader;
// 與Web服務連接
Connector.CreateInstance(__uuidof(HttpConnector));
Connector->Property[L"EndPointURL"] =
// 創(chuàng)建SoapSerializer對象
Serializer.CreateInstance(__uuidof(SoapSerializer));
// 將serializer連接到connector的輸入字符串
Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));
// 開始soap消息
Connector>BeginMessage();
// 創(chuàng)建SOAP消息
Serializer->startEnvelope("","","");
Serializer->startBody("");
Serializer->startElement("LoginTest","http://tempuri.org/","","");
Serializer->startElement("strIP","http://tempuri.org/","","");
Serializer->writeString("192.168.1.170");
Serializer->endElement();
Serializer->startElement("nPort","http://tempuri.org/","","");
Serializer->writeString("8000");
Serializer->endElement();
Serializer->endElement();
Serializer->endBody();
Serializer->endEnvelope();
// 將該soap消息發(fā)送給web服務
Connector->EndMessage();
// 讀取響應soap消息
Reader.CreateInstance(__uuidof(SoapReader));
// 將reader聯(lián)接到connector的輸出字符串
Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), "");
DWORD dwRt = GetLastError();
// 顯示結果
printf("Soap return result: %s /n",(const char *)Reader->RPCResult->text);
CoUninitialize();
上面程序將打印出Web服務的返回值。
幾點說明:
- http://localhost/MyTestWebService/Loginout.asmx 是提供Web服務的URL。
- "http://tempuri.org/"是Web服務所屬的名稱空間(如果Web服務提供者沒有指定名稱空間,將會使用該默認名稱空間)。
- 設置Property時的SoapAction就是要調用的WebMethod“http://tempuri.org/LoginTest"。我覺得稱作SoapOperation似乎更好理解些。
- Reader->RPCResult->text是調用WebMethod的string類型返回值。如果要讀取返回的參數(shù)或復雜對象,可以使用ISoapReader的相關方法。
- 另外,按上述方法,如果相關參數(shù)中含有中文,service服務器接收到的相應內容可能會是亂碼!例如我做demo時server端是基于.NET的,字符串肯定是Unicode,以兩個字節(jié)表示;而soap toolkit默認的xml編碼規(guī)則是UTF-8(使用該編碼,雖然也稱為Unicode,但是漢字會被編碼為2到3個字節(jié)不等),這就產生了沖突。解決的辦法是soap調用startEnvelope()時第三個參數(shù)指定encoding:UTF-16,這樣所有字符均是以2個字節(jié)編碼。
- 1.導入類型庫
2.需要創(chuàng)建一個SoapConnector
3.下一步創(chuàng)建SoapSerializer
4.下一步把消息附加到SoapConnector的輸入流
5.下一步讀取結果.要讀取服務器的回復,客戶端應用需要使用SoapReader,
6.SoapReader被連接到SoapConnector輸出流
7.用IXMLDOMElement對象可以從SoapReader里讀到服務器的回復