使用gSOAP与WebService - 第二部分 开发第一个WebService客户端
CurrencyConvertor - How use gSOAP and WebServices - Part 2 Doing the first WS client.
IntroductionThis 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 codeUsually 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. //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",{"xsi","http://www.w3.org/2001/XMLSchema-instance","http://www.w3.org/*/XMLSchema-instance",{"xsd","http://www.w3.org/2001/XMLSchema","http://www.w3.org/*/XMLSchema",{"ns1","http://www.webserviceX.NET/",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,ns1__ConversionRate,ns1__ConversionRateResponse) : SOAP_EOM; };
};
#endif
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 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 If this did not return In the file Soaph.h you can find methods you can use,like Using the code CMyCurrencyConvertorFor the test I have develop a new class The class I have made only a few public methods and I use them in the dialog. ConstructorIn the constructor I dynamically allocate at run time the object CMyCurrencyConvertor::CMyCurrencyConvertor()
{
m_pCurrencyConvertor= new CurrencyConvertorSoap;
}
DestructorIn the destructor I delete the memory allocated for CMyCurrencyConvertor::~CMyCurrencyConvertor() { delete m_pCurrencyConvertor; } InstantiateI have two instantiates for the params, _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,"","",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;
}
GetConversionRateI take two methods,one takes the input of string Code for currency and the other takes the type of code for currency. 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 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 .
GetSoapErrorI add another method for retrieving the error from soap to string. 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,Currency2StringThis is a useful function to convert currency to printable string and vice versa: 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 dialogI 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 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
About Dr.Luiji?(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |