VC++ 使用soapsdk和gsoap两种方法调用webservice

VC++调用webservice

有个项目用到了webserivce,在这里做个记录。

2种方法实现VC++调用webservice。

 

第一种方法,使用微软的soapsdk:

这里我们直接调用网络上免费的webserivce服务来做为用例:http://webservice.webxml.com.cn/webservices/DomesticAirline.asmx

1、需要安装微软的soapsdk3开发包,可以从微软网站下载。

2、首先在工程的BOOL CWHRepeaterApp::InitInstance()里添加::CoInitialize(NULL);

intCWHRepeaterApp::ExitInstance()里添加::CoUninitialize();用来初始化COM环境。

2、代码如下

 

#pragma once

#ifndef __CWSWrapper_H__

#define __CWSWrapper_H__

 

classCWSWrapper

{

public:

         CWSWrapper(const char *szURL,const char *szNameSpace,const char*szMethodName);

         virtual ~CRocWSWrapper(void);

 

         CStringReceiveXMLData(CString strStartCity,CString strLastCity,CString strDate,CStringstrUserID);

private:

         CStringm_strURL;

         CStringm_strNameSpace;

         CStringm_strMethodName;

};

 

#endif

 

#include "StdAfx.h"

#include "RocWSWrapper.h"

#import "msxml4.dll"

#import "C:\Program Files(x86)\Common Files\MSSoap\Binaries\mssoap30.dll" \

         exclude("IStream", "IErrorInfo","ISequentialStream", "_LARGE_INTEGER", \

         "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")

#include

 

using namespace MSXML2;

using namespace MSSOAPLib30;

usingstd::string;

 

CWSWrapper::CRocWSWrapper(constchar *szURL,constchar *szNameSpace,constchar *szMethodName)

         :m_strURL(szURL),m_strNameSpace(szNameSpace),m_strMethodName(szMethodName)

{

}

 

CString CWSWrapper::ReceiveXMLData(CString strStartCity,CStringstrLastCity,CString strDate,CString strUserID)

{

         HRESULT hr;

         ISoapSerializerPtrSerializer;

         ISoapReaderPtrReader;

         ISoapConnectorPtrConnector;

 

         try

         {

                   hr= Connector.CreateInstance(__uuidof(HttpConnector30));

                   if (FAILED(hr))

                   {

                            return CString("Error:1");

                   }

                   hr= Serializer.CreateInstance(__uuidof(SoapSerializer30));

                   if (FAILED(hr))

                   {

                            return CString("Error:2");

                   }

                   hr= Reader.CreateInstance(__uuidof(SoapReader30));

                   if (FAILED(hr))

                   {

                            return CString("Error:3");

                   }

 

 

                   Connector->Property["EndPointURL"] = (_bstr_t)m_strURL;

                   //Connector->Property["EndPointURL"] ="http://webservice.webxml.com.cn/webservices/DomesticAirline.asmx";

                   Connector->Connect();

 

                   Connector->Property["SoapAction"] =_bstr_t(m_strNameSpace+m_strMethodName);

                   //Connector->Property["SoapAction"] ="http://WebXml.com.cn/getDomesticAirlinesTime";

 

                   //创建webservice的请求soap

                   Connector->BeginMessage();

 

                   // serializer连接到connector的输入字符串

                   Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

 

                   // 创建soap消息

                   Serializer->StartEnvelope("SOAP", "http://schemas.xmlsoap.org/soap/envelope/","");

                   Serializer->SoapAttribute("xsi", "","http://www.w3.org/2001/XMLSchema-instance","xmlns");

                   Serializer->SoapAttribute("xsd", "","http://www.w3.org/2001/XMLSchema","xmlns");

 

                   Serializer->StartBody("");

                   Serializer->StartElement((_bstr_t)m_strMethodName,(_bstr_t)m_strNameSpace, "", "Soap");         //第三个参数不能填写NONE

                  

                   //下面传入四个参数,StartElementEndElement成对出现,用WriteString传入参数

                   Serializer->StartElement("startCity", "","", "Soap");

                   Serializer->WriteString((_bstr_t)strStartCity);

                   Serializer->EndElement();

                   //

                   Serializer->StartElement("lastCity", "","", "Soap");

                   Serializer->WriteString((_bstr_t)strLastCity); 

                   Serializer->EndElement();

                   //

                   Serializer->StartElement("theDate", "","", "Soap");

                   Serializer->WriteString((_bstr_t)strDate); 

                   Serializer->EndElement();

                   //

                   Serializer->StartElement("userID", "","", "Soap");

                   Serializer->WriteString((_bstr_t)strUserID); 

                   Serializer->EndElement();

                   //

                   Serializer->EndElement();

                   Serializer->EndBody();

                   Serializer->EndEnvelope();

 

                   _variant_tvar = _variant_t((IUnknown*)Connector->InputStream);

 

                   Connector->EndMessage();

 

                   //解析返回的soap

                   Reader->Load(_variant_t((IUnknown*)Connector->OutputStream),"");

                   CStringstrOutput= CString((const char*)Reader->RpcResult->text);

                   return strOutput;

         }

         catch(_com_error &e)

         {

                   ATLTRACE(("error info: %s; \n"), e.ErrorMessage());

         }

         catch(...)

         {

         }

 

         return CString("Error");

}

 

 

调用方法:

CRocWSWrapper wrapper("http://webservice.webxml.com.cn/webservices/DomesticAirline.asmx","http://WebXml.com.cn/","getDomesticAirlinesTime");

CString strName = wrapper.ReceiveXMLData(CString("天津"), CString("北京"), CString("2015-1-1"),CString(""));

 

 

第二种方法,使用gsoap:

这里我们直接调用网络上免费的webserivce服务来做为用例:http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?op=TranslatorString

http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl

在页面里可以看到服务的SOAP 请求和响应示例。(这对于第一种实现方法很直观)

1、首先下载gsoap,下载后直接解压缩即可。这里我们放到C盘下。

2、在VC工程下建立一个目录EnglishChinese,把C:\gsoap-2.8\gsoap\bin\win32目录下的wsdl2h.exe和soapcpp2.exe文件拷贝到EnglishChinese目录下,把C:\gsoap-2.8\gsoap目录下的stdsoap2.cpp和stdsoap2.h文件也拷贝到EnglishChinese目录下。此步骤可以省略。

3、在目录下建立一个批处理文件。wsdl2h和soapcpp2如何使用可以查看网络。

@echo off

wsdl2h.exe -s -otestEnCn.h http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl

soapcpp2.exe -C-IC:\gsoap-2.8\gsoap\import testEnCn.h

pause

如果第二步不拷贝文件也可以直接在gsoap目录下进行操作。CMD命令行下执行同样可以。

4、调用批处理或在CMD下运行wsdl2h.exe和soapcpp2.exe。在EnglishChinese目录下生成了一些文件。把生成的文件添加到工程里,包括soapStub.h,soapH.h,soapC.cpp和soapClient.cpp,另外把stdsoap2.cpp和stdsoap2.h文件也添加到工程里。soapClientLib.cpp文件不需要添加。此时在工程的类视图里可以看到很多以ns1__为前缀的类或接口函数等。

注意:这些添加的cpp文件由于是其它软件生成的,可能会提示错误信息:fatal errorC1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h

修改对应文件的“属性”下“C/C++”下“预编译头”下“创建/使用预编译头”为“不使用预编译头”即可。

 编译时如遇到1>stdsoap2.obj : error LNK2001: 无法解析的外部符号 _namespaces,请在stdsoap2.cpp中加上 #include "本例对应的.nsmap"文件即可通过编译。

5、添加代码,在工程的全局函数和变量中可以看到gsoap生成的函数接口。

#include "StdAfx.h"

#include "EnCn.h"

#include "EnglishChinese\soapH.h"

#include "EnglishChinese\EnglishChineseSoap.nsmap"

 

 

voidCEnCn::Test()

{

         //

        

         struct soap soap;

        

         struct _ns1__TranslatorString ns1__TranslatorString;

         struct _ns1__TranslatorStringResponse_ns1__TranslatorStringResponse;

         soap_init(&soap);

         soap_set_mode(&soap,SOAP_C_UTFSTRING); 

         ns1__TranslatorString.wordKey= "love";

 

         soap_call___ns1__TranslatorString(&soap,"http://fy.webxml.com.cn/webservices/EnglishChinese.asmx","TranslatorString",&ns1__TranslatorString,_ns1__TranslatorStringResponse);

         if (soap.error)

         {

                   ;

         }

         else

         {

                   ns1__ArrayOfString*arrStr = _ns1__TranslatorStringResponse.TranslatorStringResult;

                   int iSize = arrStr->__sizestring;

                   char **string = arrStr->string;            

         }

 

         soap_destroy(&soap);

         soap_end(&soap);

         soap_done(&soap);

}

你可能感兴趣的:(VC++ 使用soapsdk和gsoap两种方法调用webservice)