vc开发soap客户端(方式一)

 SoapSerializer

   SoapSerializer对象用来构建一个向Web服务发送的SOAP消息。在与服务器连接前,SoapSerializer对象必须与 SoapConnector对象连接。为了使这二个对象相互连接,我们需要调用SoapSerializer对象的Init方法,该方法需要一个参数 InputStream(向服务器发送数据的流):

// 创建一个SoapSerializer对象,并使用InputSTream对它进行初始化

ISoapSerializERPtr Serializer; Serializer.CreateInstance(_uuidof(SoapSerializer)); Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

  在讨论SoapSerializer的其他函数以前,我们来看一个SOAP请求的例子:

<SOAP: Envelope XMLns:SOAP="soap namespace">
<SOAP:Body>
<m:someMethodName XMLns:m="some namespace">
<someParameter> someParameterValue </someParameter>
<m:someMethodName>
</SOAP:Body>
</SOAP: Envelope>

  SOAP请求被封装在了标记中。<Envelope>标记是该SOAP文档的主标记,SOAP消息通常都被封装在<Envelope>元素中, <Envelope>元素包含一个由<Body>标记指定的消息体,该消息体包含着实际的请求。在C++中,有非常合适的方法可以创建这些标记并指定其 值。下面的代码说明了如何利用这些方法:

Serializer->startEnvelope("SOAP","","");
// 开始SOAP消息中的一个元素,第一个参数描述了名字空间,

// 如果它是空值,就会缺省地使用SOAP-ENV。第二、第三个参数

// 分别描述了URI和编码类型。
Serialzier->startBody("");

// 消息中<Body>元素的开始,第一个参数描述了编码风格Uri,其缺省的值为NONE。
Serializer->startElement("someMethodName","","","m");

// SOAP消息中<Body>元素的子元素的开始。第一个参数是子元素名字

//第二个参数是URI,第三个参数是编码类型,最后一个参数是元素的名字空间。
Serializer->WriteString("someParameterValue")

// 写元素的值

  上面以startXXX开头的函数都相应地有以endXXX开头、结束元素的函数。在完成消息后,系统会调用连接的endMessage()方法,真正开始向服务发送消息。

  现在我们已经与服务相连接,准备好了我们的请求,并将它发送给了服务。最后一个步骤就是读取来自服务器的响应。下面我们就来讨论这一问题。

  SoapReader

  该对象读取来自Web服务的响应,并将它解析为DOM,以备进一步处理之用。下面是一个来自Web服务的响应的例子:

<SOAP: Envelope xmlns:SOAP="soap namespace">
<SOAP:Body>
<m:someMethodNameResponse xmlns:m="some namespace">
<return> someResult </return>
<m:someMethodNameResponse>
</SOAP:Body>
</SOAP: Envelope>

  在调用任何方法获取结果前,我们联接OutputStream,读取存储在SoapReader对象中的响应(OutputStream用于接收来自Web服务的数据):

// 创建SOAPReader对象和与outputstream联接的代码

ISoapReaderPtr Reader; Reader.CreateInstance(_uuidof(SoapReader)); Reader->Load(_variant_t((IUnknown*)Connector->OutputStream));

// load方法也能够接收XML文档文件或字符串

  在将Web服务的响应加载到SoapReader对象后,我们可以通过调用SoapReader对象的RPCResult属性获得相应的结果, 但RPCResult并不返回真正的结果,它返回的是<Body>元素中第一个条目的第一个子元素。我们可以通过调用text属性返回真正的结果:

Reader->RPCResult->text

  一个SOAP客户端应用程序的例子

  为了说明如 何使用本篇文章中讨论的SOAP类,我们使用了http://www.xmethods.net/上列出的一项服务,该服务能够显示用户是否正在使用 Yahoo Messenger。它只需要一个参数,即Yahoo用户的登录ID。返回的结果是一个布尔型值,0表示用户不在线,1表示用户在线。

  我一直认为,学习某种编程技术的最好的方法就是实地学习源代码,在这里,我们就采取这种方法。下面是使用SOAP调用发现Yahoo用户是否在线的一个控制台应用程序的C++代码:

#include

#import "msxml3.dll"
using namespace MSXML2;

#import "C:\Program Files\Common Files\MSSoap\Binaries\MSSOAP1.dll" \
exclude("IStream", "ISequentialStream", "_LARGE_INTEGER", \
"_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")

using namespace MSSOAPLib;

void main()
{
CoInitialize(NULL);

ISoapSerializerPtr Serializer;
ISoapReaderPtr Reader;
ISoapConnectorPtr Connector;

// 与Web服务连接
Connector.CreateInstance(__uuidof(HttpConnector));
Connector->Property["EndPointURL"] = "http://www.allesta.net:51110/WebServices/soapx4/isuseronline.PHP";
Connector->Connect();

// 开始消息
Connector->Property["SoapAction"] = "uri:allesta-YahooUserPing";
Connector->BeginMessage();

// 创建SoapSerializer对象
Serializer.CreateInstance(__uuidof(SoapSerializer));

// 将serializer连接到connector的输入字符串
Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

// 创建SOAP消息
Serializer->startEnvelope("","","");
Serializer->startBody("");
Serializer->startElement("isuseronline","uri:allesta-YahooUserPing","","m");
Serializer->startElement("username","","","");
Serializer->writeString("laghari78");
Serializer->endElement();
Serializer->endElement();
Serializer->endBody();
Serializer->endEnvelope();

// 将该消息发送给web服务
Connector->EndMessage();

// 读取响应
Reader.CreateInstance(__uuidof(SoapReader));

// 将reader联接到connector的输出字符串
Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), "");

// 显示结果
printf("Answer: %s\n", (const char *)Reader->RPCResult->text);
CoUninitialize();

}

  我们可以看到,代码十分简单,即使没有使用过C++,我保证读者也能够理解上面代码的作用:首先,它与远程服务器连接;其次,它创建SOAP消息并向web服务发送该消息;最后,读取服务器的响应,并使用printf将它输出到屏幕上。

  结论

  在本篇文章中,我们讨论了如何使用Visual C++建立一个简单的SOAP客户端应用程序。我们还学习了SOAP Toolkit中的几个方法以及如何使用SOAP从服务器获取数据。希望通过本篇文章,使读者能够掌握如何使用C++开发SOAP客户端应用程序。 

  最后:大家最关心如何注册soap里的dll,SOAP只需要如下文件: MSSOAP30.DLL MSSOAPR3.DLL WISC30.dll MSXML4只需要如下文件: msxml4r.dll msxml4.dll 注意:文件注册顺序也如上所列顺序。保证能用。你自己写个批处理在打包的时候一起打包就OK了

 

其他方式: http://blog.csdn.net/Tr0j4n/archive/2009/12/25/5077787.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include "stdafx.h" #import "msxml4.dll" using namespace MSXML2; #import "C:/Program Files/Common Files/MSSoap/Binaries/mssoap30.dll" \ exclude("IStream", "IErrorInfo", "ISequentialStream", \ "_LARGE_INTEGER", "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME") using namespace MSSOAPLib30; //你机器得安装SOAP Toolkit3.0 ,1.0时,用using namespace时报错 void query(char *EndPointURL,char *NameSpace,char *method,int argv_len,char* args[],char* argv[]) { ISoapSerializerPtr Serializer; ISoapReaderPtr Reader; ISoapConnectorPtr Connector; // Connect to the service Connector.CreateInstance(__uuidof(HttpConnector30)); Connector->Property["EndPointURL"] = EndPointURL;//"http://localhost/WebService1/Service1.asmx"; Connector->Connect();//和服务器连接 // Begin message Connector->Property["SoapAction"] = _bstr_t(NameSpace) + _bstr_t(method);//"http://xin.org/getIP"; Connector->BeginMessage(); Serializer.CreateInstance(__uuidof(SoapSerializer30)); // 将serializer连接到connector的输入字符串 Serializer->Init(_variant_t((IUnknown*)Connector->InputStream)); // 创建SOAP消息 Serializer->StartEnvelope("","",""); Serializer->StartBody(""); Serializer->StartElement(method,NameSpace,"","");//命名空间必须有 for(int i=0;i<argv_len;i++) { Serializer->StartElement(args[i],NameSpace,"",""); Serializer->WriteString(argv[i]); Serializer->EndElement(); } Serializer->EndElement(); Serializer->EndBody(); Serializer->EndEnvelope(); // Send the message to the web service Connector->EndMessage(); // 读取响应 Reader.CreateInstance(__uuidof(SoapReader30)); // 将reader联接到connector的输出字符串 Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), ""); printf("Answer: %s\n",(const char*) Reader->RpcResult->text); } int main(int argc, char* argv[]) { CoInitialize(NULL); char *EndPointURL="http://approve.share-su
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值