现在的位置: 首页 > 综合 > 正文

易懂易上手WebService客户端——C++之SoapTookit——附源码例子插件

2013年12月09日 ⁄ 综合 ⁄ 共 3182字 ⁄ 字号 评论关闭

博客背景介绍:

呵呵,因为客户的系统是C++版,公司开发工作流是Java版,两者可搭不上话啊,所以哩,C++通信客户端就诞生了。为了协调客户C++与公司JavaC++通信客户端可得发挥其作用了。并且客户C++C/S结构,而公司Java工作流可是纯纯的B/S结构,所以C++通信客户端这块工作也是需要来协调的。

那就谈谈C++java通信方式websericewebserivce不分语言,实际上是一种通信的接口而已。

这篇博客主要讲解一下C++调用WebService,也就是C++作为客户端——soapTookit

SoapTookit方式比较简单,易懂。并且是自己手写编码,既然是手动编码,则会容易封装。另一种客户端方式gSoap方式,其中个Soap方式使用的命令行工具,命令行工具替我们产生很多头文件,但是个Soap不知如何封装客户端,所以选择了简单易懂的SoapTookit

使用SoapTookit方式开发WebService客户端,需要安装soapTookit插件。一般安装soapTookit3.0版本。SoapTookit3.0插件会传到网上,方便大家下载。

使用SoapTookit方式开发WebService,编程步骤类似java中的jdbc编程。

首先:创建连接对象。

     ISoapConnectorPtr connector; 
     Connector.CreateInstance(__uuidof(HttpConnector30));

第二:指定连接服务器的地址。

Connector->Property ["EndPointURL"]=http://localhost:8080/Test/test;

服务器地址,也就是wsdl文件的地址,地址后面可以添加”?wsdl”

如:Connector->Property["EndPointURL"] =http://localhost:8080/Test/test?wsdl;

第三:真正连接服务器。

Connector->Connect();

第四:指定连接服务器上某个动作(方法)。

封装你访问那个方法,比如求和方法,方法名:sum

Connector->Property ["SoapAction"]= "urn:sum";

为了防止写错,也可以写成与第二步一样,直接写wsdl路径。

如:Connector->Property["SoapAction"]= “http://localhost:8080/Test/test”

第五:给第四步中的方法中传递消息(传递参数赋值——输入流)  

      // 创建SoapSerializer对象,并用InputSTream进行初始化。
      ISoapSerializerPtr Serializer; 
      Serializer.CreateInstance(_uuidof(SoapSerializer30)); 
      Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

     //真正发送消息
     Serializer->startEnvelope("","",""); 
  // 开始处理SOAP消息。第一个参数是命名空间,缺省为SOAP-ENV。
  // 第二个参数定义URI。第三个参数定义Serialzier->startBody("")函数的编码方式。
  // 开始处理<Body>元素,第一个参数是URI的编码类型,缺省为NONE。
   Serializer->StartBody("");
	Serializer->StartElement("sum","http://sum","","m");
   // 开始处理Body里的子元素。
  // 第一个参数是元素名。第二个参数是URI。
  // 第三个参数编码类型。第四个参数是元素的命名空间。
	Serializer->StartElement("a","","","");
	Serializer->WriteString("10");
	Serializer->EndElement();

	Serializer->StartElement("b","","","");
	Serializer->WriteString("20");
	Serializer->EndElement();
	
               Serializer->EndElement();
	Serializer->EndBody();
	Serializer->EndEnvelope();

   仔细观察,可以发现,startend是匹配的。

第六:读取服务器返回值(输出流方式)

ISoapReaderPtr Reader;
Reader.CreateInstance(__uuidof(SoapReader30));
// Connect the reader to the output stream of the connector object.
 Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), "");
// Display the result.
 printf("Answer: %s\n", (const char*)Reader->RpcResult->text);

开发过程中,需要注意的几个事项:

若返回的结果是:soap server,说明没有匹配上,比如参数名称不对或者输入参数不合格,没有相应的结果。

输入参数中,writeString,只能输出string类型。在c++中输入字符数组或者字符串指针形式。

若是输入参数是int,或long类型,还必须转化成char数组形式或char*形式。

在转化的过程中,注意longint在内存的长度。

输出结果时,不能只能return (constchar*)Reader->RpcResult->text,因为方法结束后,指针也消亡了,所以会提示错误。需要把结果赋值copy到一个字符串中,然后再返回。

若是返回intlong类型时,则再次由char*转化成intlong类型。

若方法中参数是数组,如何传输呢?

 

只要把参数名写一样,即可。比如上述sum方法中a是数组参数,则: 

 	Serializer->StartElement("a","","","");
	Serializer->WriteString("10");
	Serializer->EndElement();

	Serializer->StartElement("a","","","");
	Serializer->WriteString("10");
	Serializer->EndElement();

     在操作中,需要引入soapTookit3.0中相应的dll表头文件。

    

#import "msxml4.dll" 
using namespace MSXML2;
//mssoap3.0.dll路径(视情况而定)
#import"C:/ProgramFiles/CommonFiles/MSSoap/Binaries/mssoap30.dll" /
exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER", /
"_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")
using namespace MSSOAPLib30;

    所谓的注意事项,是在开发过程中经验吧。SoapTookit插件以及demo源码,我会及时上传的。

后期会继续总结开发webserivce客户端另一种方式gsoap以及开发webserivce服务器端方式gsoap,并且会详细阐述在开发遇到的问题以及解决的方案。

 soapTookit客户端源码以及需要安装的插件已经上传到了

 

抱歉!评论已关闭.