使用线传输技术为 MS SOAP Toolkit 1.0 开发的 C++ SOAP 客户端






4.67/5 (3投票s)
使用线传输技术为 2000 年 12 月发布的 MS SOAP Toolkit 1.0 开发的 C++ SOAP 客户端
要求
引言
2000 年 7 月,微软发布了 Visual Studio 6.0 的第一个 SOAP Toolkit 版本。2000 年 9 月,发布了 SOAP Toolkit 版本 1.0 的 Beta 1 版本。我认为最显著的特性是增加了 SSL 支持。最新的非 Beta 版本是 2000 年 12 月的版本,修复了错误并对暴露的接口进行了小幅更改。本文的目的是演示使用 C++ 客户端和 ATL 使用线传输技术。
关于示例
MS 为了测试目的,提供了 Web 服务。Web 服务的描述可以在以下 链接 中找到。该示例使用此 Web 服务,并演示了执行此 Web 服务暴露的 GetStockQuote
方法。该示例包含两种方法,Connect 和 GetStockMethod。
Connect 方法
此方法用于从 Web 服务获取服务描述和 URI 侦听器。这是两个 string
(BSTR)我们将保留用于在 GetStockMethod
中使用。
long nSuccess, item = 0;
CComVariant varTemp;
ROPE::ISOAPPackagerPtr packer;
CComPtr<IUnknown> pIUnknown;
ROPE::IServiceDescriptorsPtr pIServiceDescriptors;
ROPE::ISDEndPointInfoPtr pISDEndPointInfo;
USES_CONVERSION;
try
{
HRESULT hr = packer.CreateInstance( ROPE::CLSID_SOAPPackager );
//load service description from this web service
hr = packer->LoadServicesDescription(ROPE::icURI,
bstrLocation, NULL, &nSuccess);
if( nSuccess != 1 )
throw E_FAIL;
//get service descriptors
hr = packer->get_GetServiceDescriptors(ROPE::icENDPOINTINFO, &varTemp);
pIUnknown.Attach( varTemp.pdispVal );
pIUnknown.QueryInterface( &pIServiceDescriptors );
//get first descriptor on the list
VariantInit(&varTemp);
hr = pIServiceDescriptors->get_Item(variant_t(item),&varTemp);
pIUnknown.Detach();
//get the endpoint(URI address) a.e. where the SOAP message will be sent
pIUnknown.Attach( varTemp.pdispVal );
hr = pIUnknown.QueryInterface( &pISDEndPointInfo );
hr = pISDEndPointInfo->get_URI(&URI_LISTENER);
//get the service description
hr = packer->get_ServicesDescription(&bstrSrvDesc);
}
catch(...)
{
std::cout << "Connection failure ! "<< std::endl;
return false;
}
std::cout << "Connection successful "<< std::endl;
return true;
GetStockMethod
此方法用于调用 Web 服务暴露的 GetStockPrice
方法。在创建新的 SOAPPackager
对象并从 Connect
方法获得的 string
加载服务描述后,将创建有效负载并发布(使用新的 WireTransfer
对象)到 Web 服务,并将显示结果
long nSuccess;
CComBSTR bstrRequestStruct, bstrRequestPayload, bstrResponsePayload;
CComVAriant varPrice;
ROPE::ISOAPPackagerPtr packer;
ROPE::IWireTransferPtr wireTrans;
USES_CONVERSION;
try
{
HRESULT hr = packer.CreateInstance( ROPE::CLSID_SOAPPackager );
//load service description using the string from previous Connect method call
hr = packer->LoadServicesDescription(ROPE::icSTRING,
bstrSrvDesc, NULL, &nSuccess);
if( nSuccess != 1 )
throw E_FAIL;
//seek in the service description
//the method structure a.e. what we need to call this method
hr = packer->GetMethodStruct(CComBSTR("GetStockQuote"), ROPE::icINPUT, &bstrRequestStruct);
// set method name
hr = packer->SetPayloadData(ROPE::icREQUEST, CComBSTR(""),
CComBSTR("GetStockQuote"), bstrRequestStruct);
//set method parameters
hr = packer->SetParameter( ROPE::icREQUEST, CComBSTR("Symbol"), CComVariant("MSFT") );
hr = packer->SetParameter( ROPE::icREQUEST,
CComBSTR("description"), CComVariant("any company") );
//get the data that will be sent to web server( payload )
hr = packer->GetPayload( ROPE::icREQUEST, &bstrRequestPayload);
std::cout << W2A(bstrRequestPayload) << std::endl << std::endl;
//post the payload
wireTrans.CreateInstance( ROPE::CLSID_WireTransfer);
hr = wireTrans->AddStdSOAPHeaders(URI_LISTENER,CComBSTR("GetStockQuote"),
bstrRequestPayload.Length());
hr = wireTrans->PostDataToURI(URI_LISTENER, bstrRequestPayload, &bstrResponsePayload);
std::cout << W2A(bstrResponsePayload) << std::endl << std::endl;
//this is the response from service
hr = packer->SetPayload( ROPE::icRESPONSE, bstrResponsePayload);
//get return value
hr = packer->GetParameter( ROPE::icRESPONSE, CComBSTR("result"), &varPrice);
std::cout << W2A(varPrice.bstrVal) << std::endl;
}
catch(...)
{
std::cout << "Something wrong happened !" << std::endl<< std::endl;
}
结论
我希望您会发现这种方法有用。