使用gSOAP与WebService - 第二部分 开发第一个WebService客户端(C++)
2007-03-13 09:49
567 查看
CurrencyConvertor - How use gSOAP and WebServices - Part 2 Doing the first WS client.
Download Demo Project - 42.1 KB
Download Source Files - 219.6 KB
Collapse
In this case, the method is only one and it is
The class takes two params. The first is the input (the two currencies) and the second is the output (the result).
Before you use the class method of WS you must instantiate the param with
This returns an int that is
If this did not return
In the file Soaph.h you can find methods you can use, like
The class
I have made only a few public methods and I use them in the dialog.
Collapse
Collapse
I create the two param pointers and instantiate it. I set the two currency code and call the
If all works fine, I return the conversion, otherwise I return an error.
With this method you can call the function without knowing the internal type. For the conversion I use the function
Collapse
Collapse
I take a cycle for retrieval, and display the currency code, like this:
When you push a button I retrieve the currency codes selected and use
Use it however you wish.
Download Demo Project - 42.1 KB
Download Source Files - 219.6 KB
Introduction
This is the second of two articles where I explain building a web service client from wsdl file. With Part One, I explained how to get the class from the wsdl file to be used in VC++ 6. In Part Two, I will show you how to use the classes generated with gSOAP in Part One.Using the code
Usually in the file soap*****************SoapProxy.h we can find the class definition of generic WS. In this case, soapCurrencyConvertorSoapProxy.h, I have already included it in Part One.Collapse
//soapCurrencyConvertorSoapProxy.h #ifndef soapCurrencyConvertorSoap_H #define soapCurrencyConvertorSoap_H #include "soapH.h" class CurrencyConvertorSoap { public: struct soap *soap; const char *endpoint; CurrencyConvertorSoap() { soap = soap_new(); endpoint = "http://www.webservicex.net/CurrencyConvertor.asmx"; if (soap && !soap->namespaces) { static const struct Namespace namespaces[] = { {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/*/soap-envelope", NULL}, {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.org/*/soap-encoding", NULL}, {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL}, {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL}, {"ns1", "http://www.webserviceX.NET/", NULL, NULL}, {NULL, NULL, NULL, NULL} }; soap->namespaces = namespaces; } }; virtual ~CurrencyConvertorSoap() { if (soap) { soap_destroy(soap); soap_end(soap); soap_done(soap); soap_del(soap); } }; virtual int __ns1__ConversionRate(_ns1__ConversionRate *ns1__ConversionRate, _ns1__ConversionRateResponse *ns1__ConversionRateResponse) { return soap ? soap_call___ns1__ConversionRate(soap, endpoint, NULL, ns1__ConversionRate, ns1__ConversionRateResponse) : SOAP_EOM; }; }; #endif
In this case, the method is only one and it is
__ns1__ConversionRate.
The class takes two params. The first is the input (the two currencies) and the second is the output (the result).
Before you use the class method of WS you must instantiate the param with
soap_instantiate(), and with
soap, from your
CurrencyConvertorexample.
pConversionRate = (_ns1__ConversionRate*) soap_instantiate(m_pCurrencyConvertor->soap, SOAP_TYPE__ns1__ConversionRate,"", "",pConversionRateSize); and pConversionRateResponse = (_ns1__ConversionRateResponse*) soap_instantiate(m_pCurrencyConvertor->soap, SOAP_TYPE__ns1__ConversionRateResponse,/ "","",pConversionRateResponseSize);
This returns an int that is
SOAP_OK, if all is well. (Note: You can find all other definitions for errors in stdsopa2.h)
If this did not return
SOAP_OKyou can use
soap_print_faultto get the error string.
In the file Soaph.h you can find methods you can use, like
soap_s2ns1__Currencyor
soap_ns1__Currency2s. Just as the name explains, they are used to convert the currency to string and vice versa.
Using the code CMyCurrencyConvertor
For the test I have develop a new classCMyCurrencyConvertorthat replaces the methods of CurrencyConvertor.
The class
CMyCurrencyConvertorinstantiates all the created pointers itself.
I have made only a few public methods and I use them in the dialog.
Constructor
In the constructor I dynamically allocate at run time the objectCurrencyConvertorSoap.
CMyCurrencyConvertor::CMyCurrencyConvertor() { m_pCurrencyConvertor= new CurrencyConvertorSoap; }
Destructor
In the destructor I delete the memory allocated forCurrencyConvertorSoap.
CMyCurrencyConvertor::~CMyCurrencyConvertor() { delete m_pCurrencyConvertor; }
Instantiate
I have two instantiates for the params,InstantiateRateand
InstantiateRateResponse.
Collapse
_ns1__ConversionRate * CMyCurrencyConvertor::InstantiateRate() { _ns1__ConversionRate *pConversionRate; size_t *pConversionRateSize = new size_t; *pConversionRateSize = sizeof(_ns1__ConversionRate); pConversionRate = (_ns1__ConversionRate*) soap_instantiate(m_pCurrencyConvertor->soap, SOAP_TYPE__ns1__ConversionRate,"","", pConversionRateSize); delete pConversionRateSize ; return pConversionRate; } _ns1__ConversionRateResponse * CMyCurrencyConvertor::InstantiateRateResponse() { _ns1__ConversionRateResponse *pConversionRateResponse; size_t *pConversionRateResponseSize = new size_t; *pConversionRateResponseSize = sizeof(_ns1__ConversionRateResponse); pConversionRateResponse = (_ns1__ConversionRateResponse*) soap_instantiate(m_pCurrencyConvertor->soap , / SOAP_TYPE__ns1__ConversionRateResponse,"", "",pConversionRateResponseSize); delete pConversionRateResponseSize ; return pConversionRateResponse; }
GetConversionRate
I take two methods, one takes the input of string Code for currency and the other takes the type of code for currency.Collapse
bool CMyCurrencyConvertor::GetConversionRate(ns1__Currency oFromCurrencyCode,
ns1__Currency oToCurrencyCode, double &dRate)
{
int iRet = SOAP_ERR;
_ns1__ConversionRate *pConversionRate;
_ns1__ConversionRateResponse *pConversionRateResponse;
pConversionRate = InstantiateRate();
pConversionRateResponse = InstantiateRateResponse();
pConversionRate->FromCurrency = oFromCurrencyCode;
pConversionRate->ToCurrency = oToCurrencyCode;
iRet = m_pCurrencyConvertor->__ns1__ConversionRate(pConversionRate,
pConversionRateResponse);
switch(iRet)
{
case SOAP_OK:
{
dRate = pConversionRateResponse->ConversionRateResult;
return true;
}
/*
case SOAP_CLI_FAULT
case SOAP_SVR_FAULT
case SOAP_TAG_MISMATCH
case SOAP_TYPE
case SOAP_SYNTAX_ERROR
case SOAP_NO_TAG
case SOAP_IOB
case SOAP_MUSTUNDERSTAND
...
*/
default:
{
Log(GetSoapError());
}
}
return false;
}
I create the two param pointers and instantiate it. I set the two currency code and call the
ConversionRate.
If all works fine, I return the conversion, otherwise I return an error.
// Conversion from String code bool CMyCurrencyConvertor::GetConversionRate(CString sFromCurrencyCode, CString sToCurrencyCode, double &dRate) { ns1__Currency oFromCurrencyCode; ns1__Currency oToCurrencyCode; int iRetFromCurrencyCode = soap_s2ns1__Currency (m_pCurrencyConvertor->soap,sFromCurrencyCode, &oFromCurrencyCode); int iRetToCurrencyCode = soap_s2ns1__Currency (m_pCurrencyConvertor->soap,sToCurrencyCode, &oToCurrencyCode); return GetConversionRate(oFromCurrencyCode,oToCurrencyCode,dRate); }
With this method you can call the function without knowing the internal type. For the conversion I use the function
soap_s2ns1__Currency.
GetSoapError
I add another method for retrieving the error from soap to string.Collapse
CString CMyCurrencyConvertor::GetSoapError() { struct soap *pSoap = m_pCurrencyConvertor->soap; CString sError; if (soap_check_state(pSoap )) sError.Format("Error: soap struct not initialized/n"); else { if (pSoap->error) { const char *pFaultCode, *pFaultSubCode = NULL, *pFalutString, **iFaultCode; iFaultCode = soap_faultcode(pSoap ); if (!*iFaultCode) soap_set_fault(pSoap ); pFaultCode = *iFaultCode; if (pSoap ->version == 2) pFaultSubCode = *soap_faultsubcode(pSoap ); pFalutString = *soap_faultstring(pSoap ); iFaultCode = soap_faultdetail(pSoap ); sError.Format("%s%d fault: %s [%s]/"%s/"Detail: %s", pSoap->version ? "SOAP 1." :/ "Error ", pSoap->version ? (int)pSoap->version : pSoap->error, pFaultCode, / pFaultSubCode ? pFaultSubCode : "no subcode", pFalutString ? pFalutString : "[no reason]", / iFaultCode && *iFaultCode ? *iFaultCode : "[no detail]"); } } return sError; }
String2Currency, Currency2String
This is a useful function to convert currency to printable string and vice versa:Collapse
bool CMyCurrencyConvertor::String2Currency(CString sCurrencyCode,
ns1__Currency &oCurrencyCode)
{
int iRet = soap_s2ns1__Currency(m_pCurrencyConvertor->soap,
sCurrencyCode, &oCurrencyCode);
switch(iRet)
{
case SOAP_OK:
{
return true;
}
/*
case SOAP_CLI_FAULT
case SOAP_SVR_FAULT
case SOAP_TAG_MISMATCH
case SOAP_TYPE
case SOAP_SYNTAX_ERROR
case SOAP_NO_TAG
case SOAP_IOB
case SOAP_MUSTUNDERSTAND
...
*/
default:
{
Log(GetSoapError());
}
}
return false;
}
bool CMyCurrencyConvertor::Currency2String(ns1__Currency oCurrencyCode,
CString &sCurrencyCode)
{
const char* sName =
soap_ns1__Currency2s(m_pCurrencyConvertor->soap,oCurrencyCode);
if (sName != NULL)
{
CString sTMP(sName);
sCurrencyCode = sTMP;
return true;
}
else
Log(GetSoapError());
return false;
}
Using the code in dialog
I created a dialog project and I use the methods I describe again.I take a cycle for retrieval, and display the currency code, like this:
CString sCodeName; for (int iDx=ns1__Currency__AFA; iDx <;ns1__Currency__TRY+1; iDx++) { m_oMyCurrencyConvertor.Currency2String((ns1__Currency) iDx, sCodeName); m_cboFromCurrency.AddString(sCodeName); m_cboToCurrency.AddString(sCodeName); }
When you push a button I retrieve the currency codes selected and use
GetConversionRateto call WS.
double dRate; CString sFromCurrency,sToCurrency; m_cboFromCurrency.GetWindowText(sFromCurrency); m_cboToCurrency.GetWindowText(sToCurrency); if (m_oMyCurrencyConvertor.GetConversionRate(sFromCurrency, sToCurrency,dRate)) { int iColumnCount = m_lstConversionRate.GetItemCount(); CString sRate; sRate.Format("%f",dRate); m_lstConversionRate.InsertItem(iColumnCount,sFromCurrency); m_lstConversionRate.SetItemText(iColumnCount,iIDX_TO,sToCurrency); m_lstConversionRate.SetItemText(iColumnCount,iIDX_CONVERSION,sRate); }
Use it however you wish.
History
12/07/2006: First releaseAbout Dr.Luiji
Bertoneri Luigi, alias Dr.Luiji Bachelor of Science in Computer science, year 2000 - University of Pisa (Italy). I currently live in Italy. Music I listen to: Slipknot, Type O Negative, Tool, Mushroomhead, Dry Kill Logic, System of a Down, White Zombie, RA, Slayer. Click here to view Dr.Luiji's online profile. |
相关文章推荐
- 使用GSoap开发WebService客户端与服务端
- 使用GSoap开发WebService客户端与服务端
- 第二部分:使用Jasperreport作为报表控件开发胖客户端报表应用
- 第二部分:使用Jasperreport作为报表控件开发胖客户端报表应用
- gSoap入门之三__C++开发的简单WebService客户端程序
- 在Linux下,利用gSoap生成的WebService客户端进行开发时遇到的问题
- 使用CXF开发WebService客户端
- 基于ONVIF协议的(IPC)客户端程序开发-3:使用gSOAP生成Web Services框架代码
- Linux平台下基于C++语言使用gSOAP开发Web Service服务端和客户端程序
- 使用java6开发WebService服务端和客户端
- 使用WSDL发布WebService(第二部分)简单对象访问协议——学习SOAP语法和使用SOAP发布WSDL
- 使用Axis2开发webservice服务端接口+axis开发的客户端调用
- 使用CXF开发WebService客户端
- 1. 使用JDK开发WebService客户端和服务端
- 第二部分:Shader Authoring with HLSL(使用HLSL编写开发shader)
- 使用netbeans6.7.1开发webservice 服务端 和 客户端(转)
- 使用CXF框架开发WebService客户端
- 使用WSDL发布WebService(第二部分)简单对象访问协议——学习SOAP语法和使用SOAP发布WSDL
- 使用gSOAP进行Webservice开发总结
- C++中如何使用gsoap开发WebService