- Get link
- X
- Other Apps
Featured Post
Posted by
Varun
on
- Get link
- X
- Other Apps
What is SOAP?
SOAP(Simple Object Access Protocol) is a great way to exchange information over the network. Normally it is used with application protocols like HTTP, SMTP etc. The envelope containing the information is XML based.
It provides the basic messaging infrastructure for web services.
An example SOAP request looks like :
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<ns1:RequestHeader
soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next"
soapenv:mustUnderstand="0"
xmlns:ns1="https://www.google.com/apis/ads/publisher/v201403">
<ns1:networkCode>123456</ns1:networkCode>
<ns1:applicationName>DfpApi-Java-2.1.0-dfp_test</ns1:applicationName>
</ns1:RequestHeader>
</soapenv:Header>
<soapenv:Body>
<getAdUnitsByStatement xmlns="https://www.google.com/apis/ads/publisher/v201403">
<filterStatement>
<query>WHERE parentId IS NULL LIMIT 500</query>
</filterStatement>
</getAdUnitsByStatement>
</soapenv:Body>
</soapenv:Envelope>
The corresponding response would look like :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<ResponseHeader xmlns="https://www.google.com/apis/ads/publisher/v201403">
<requestId>xxxxxxxxxxxxxxxxxxxx</requestId>
<responseTime>1063</responseTime>
</ResponseHeader>
</soap:Header>
<soap:Body>
<getAdUnitsByStatementResponse xmlns="https://www.google.com/apis/ads/publisher/v201403">
<rval>
<totalResultSetSize>1</totalResultSetSize>
<startIndex>0</startIndex>
<results>
<id>2372</id>
<name>RootAdUnit</name>
<description></description>
<targetWindow>TOP</targetWindow>
<status>ACTIVE</status>
<adUnitCode>1002372</adUnitCode>
<inheritedAdSenseSettings>
<value>
<adSenseEnabled>true</adSenseEnabled>
<borderColor>FFFFFF</borderColor>
<titleColor>0000FF</titleColor>
<backgroundColor>FFFFFF</backgroundColor>
<textColor>000000</textColor>
<urlColor>008000</urlColor>
<adType>TEXT_AND_IMAGE</adType>
<borderStyle>DEFAULT</borderStyle>
<fontFamily>DEFAULT</fontFamily>
<fontSize>DEFAULT</fontSize>
</value>
</inheritedAdSenseSettings>
</results>
</rval>
</getAdUnitsByStatementResponse>
</soap:Body>
</soap:Envelope>
Courtesy : https://developers.google.com/doubleclick-publishers/docs/soap_xmlThe above is an example of Google's web service which provides Ad Units to the requester based on some filters.
Web Services provide an easy platform independent way to exchange information over the network.
The following picture shows the basic flow on how the Service Provider caters the request of the consumer.
Source: http://www.service-architecture.com |
The example uses gSoap library for SOAP encoding/decoding and Xerces library to extract the data from the SOAP response (XML).
I have used the web service URL http://www.webservicex.net/stockquote.asmx?WSDL
Resources:
- gSOAP library (2.8.18) http://sourceforge.net/projects/gsoap2/files/
- Xerces library (3.1.1) http://xerces.apache.org/mirrors.cgi#binary
Setup for Visual Studio 2005:
- Unzip gSOAP library at any location (Lets say C:\tools , so the location will be C:\gsoap-2.8)
- Download only the binary distribution of xerces xerces-c-3.1.1-x86-windows-vc-8.0.zip
- Unzip the zip file at C:\ so that location becomes C:\xerces-c-3.1.1-x86-windows-vc-8.0
- Create an empty Win32 Console Application project.
- Add theses paths to the Additional Include Directories :
"C:\xerces-c-3.1.1-x86-windows-vc-8.0\include";"C:\gsoap-2.8\gsoap\";"C:\gsoap-2.8\gsoap\import"
- Add these paths to Additional Library Directories :
"C:\xerces-c-3.1.1-x86-windows-vc-8.0\lib"
- Add these libs to the dependency list:
Notice that since we are using a Debug configuration here, we added xerces-c_3D.lib. For Release configuration, use xerces-c_3.lib - Open a command prompt and go to gSOAP win32 bin directory and run following commands :
wsdl2h.exe -o quote.h http://www.webservicex.net/stockquote.asmx?WSDL
This will generate quote.h which contains class definitions for the web service.
soapcpp2.exe /IC:\tools\gsoap_2.8.18\gsoap-2.8\gsoap\import quote.h
This generates following files :
StockQuoteSoap.GetQuote.req.xml
StockQuoteSoap.GetQuote.res.xml
StockQuoteSoap.nsmap
soapC.cpp
soapClient.cpp
soapClientLib.cpp
soapH.h
soapServer.cpp
soapServerLib.cpp
soapStub.h - Now add these generated files to the Visual Studio project created earlier :
soapH.h , soapC.cpp, soapClient.cpp, soapStub.h, quote.h
Also these add two additional files from C:\tools\gsoap_2.8.18\gsoap-2.8\gsoap to your project:
stdsoap2.cpp, stdsoap2.h - Now its time to create some files on our own :). Create these files in the project and copy the contents from the code below :
quote.cpp, parser.hpp, stock.hpp - Now the project is ready to compile. Use F7 to compile the solution.
- After the binary is generated, run it like this :
<binary-name>.exe<space><Ticker-Name>
e.g. If project name was soap
soap.exe GOOG - This program is specific to the Stock Quote web service provided by http://www.webservicex.net/ . This program can be modified to use any web service. Depending upon the expected SOAP response, the result can be parsed accordingly. Then following files will be modified :
stock.hpp - Class which stores the data from SOAP response
parser.hpp - Class which parses the XML result from SOAP response
SOAP Web Service client implementation(c++)
//quote.cpp
#include "soapH.h" // include the generated proxy
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMNodeIterator.hpp>
#include <xercesc/dom/DOMNodeList.hpp>
#include <xercesc/dom/DOMText.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLUni.hpp>
#include "parser.hpp"
XERCES_CPP_NAMESPACE_USE
GetXml::GetXml()
{
try
{
XMLPlatformUtils::Initialize(); // Initialize Xerces infrastructure
}
catch( XMLException& e )
{
char* message = XMLString::transcode( e.getMessage() );
std::cout << "XML toolkit initialization error: " << message << std::endl;
XMLString::release( &message );
}
// Tags and attributes used in XML file.
// Can't call transcode till after Xerces Initialize()
TAG_root = XMLString::transcode("StockQuotes");
TAG_Stock = XMLString::transcode("Stock");
TAG_Symbol = XMLString::transcode("Symbol");
TAG_Last = XMLString::transcode("Last");
TAG_Date = XMLString::transcode("Date");
TAG_Time = XMLString::transcode("Time");
TAG_Change = XMLString::transcode("Change");
TAG_Open = XMLString::transcode("Open");
TAG_High = XMLString::transcode("High");
TAG_Low = XMLString::transcode("Low");
TAG_Volume = XMLString::transcode("Volume");
TAG_MktCap = XMLString::transcode("MktCap");
TAG_PrevClose = XMLString::transcode("PreviousClose");
TAG_PercentChange = XMLString::transcode("PercentageChange");
TAG_AnnRange = XMLString::transcode("AnnRange");
TAG_Earns = XMLString::transcode("Earns");
TAG_PE = XMLString::transcode("P-E");
TAG_Name = XMLString::transcode("Name");
m_XmlParser = new XercesDOMParser;
m_Stock = new Stock;
}
GetXml::~GetXml()
{
// Free memory
delete m_XmlParser;
delete m_Stock;
try
{
XMLString::release( &TAG_root );
}
catch( ... )
{
std::cout << "Unknown exception encountered in Destructor" << std::endl;
}
// Terminate Xerces
try
{
XMLPlatformUtils::Terminate(); // Terminate after release of memory
}
catch( xercesc::XMLException& e )
{
char* message = xercesc::XMLString::transcode( e.getMessage() );
std::cout << "XML toolkit teardown error: " << message << std::endl;
XMLString::release( &message );
}
}
void GetXml::readXml(std::string& xmlStr)
throw( std::runtime_error )
{
// Configure DOM parser.
m_XmlParser->setValidationScheme( XercesDOMParser::Val_Never );
m_XmlParser->setDoNamespaces( false );
m_XmlParser->setDoSchema( false );
m_XmlParser->setLoadExternalDTD( false );
try
{
xercesc_3_1::MemBufInputSource xmlBuf((const XMLByte*)xmlStr.c_str(), xmlStr.size(),
"xmlBuf (in memory)");
m_XmlParser->parse( xmlBuf );
xercesc_3_1::DOMDocument* xmlDoc = m_XmlParser->getDocument();
DOMElement* elementRoot = xmlDoc->getDocumentElement();
if( !elementRoot ) throw(std::runtime_error( "Empty XML document" ));
DOMNodeList* children = elementRoot->getChildNodes();
const XMLSize_t nodeCount = children->getLength();
// For all nodes, children of "StockQuotes" in the XML tree.
for( XMLSize_t xx = 0; xx < nodeCount; ++xx )
{
DOMNode* currentNode = children->item(xx);
if( currentNode->getNodeType() && // true is not NULL
currentNode->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
{
// Found node which is an Element. Re-cast node as element
DOMElement* currentElement
= dynamic_cast< xercesc::DOMElement* >( currentNode );
if( XMLString::equals(currentElement->getTagName(), TAG_Stock))
{
DOMNodeList* children1 = currentElement->getChildNodes();
const XMLSize_t nodeCount1 = children1->getLength();
for( XMLSize_t yy = 0; yy < nodeCount1; ++yy )
{
DOMNode* currentNode1 = children1->item(yy);
if( currentNode1->getNodeType() && // true is not NULL
currentNode1->getNodeType() == DOMNode::ELEMENT_NODE ) // is element
{
// Found node which is an Element. Re-cast node as element
DOMElement* currentElement1
= dynamic_cast< xercesc::DOMElement* >( currentNode1 );
std::cout<<XMLString::transcode(currentElement1->getTagName())<<": "
<<XMLString::transcode(currentElement1->getTextContent())<<std::endl;
std::string sym(XMLString::transcode(currentElement1->getTextContent()));
if(XMLString::equals(currentElement1->getTagName(), TAG_Symbol))
{
m_Stock->SetSymbol(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Last))
{
m_Stock->SetLast(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Date))
{
m_Stock->SetDate(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Time))
{
m_Stock->SetTime(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Change))
{
m_Stock->SetChange(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Open))
{
m_Stock->SetOpen(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_High))
{
m_Stock->SetHigh(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Low))
{
m_Stock->SetLow(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Volume))
{
m_Stock->SetVolume(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_MktCap))
{
m_Stock->SetMktCap(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_PrevClose))
{
m_Stock->SetPrevClose(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_PercentChange))
{
m_Stock->SetPercentChange(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_AnnRange))
{
m_Stock->SetAnnRange(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Earns))
{
m_Stock->SetEarns(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_PE))
{
m_Stock->SetPE(sym);
}
else if(XMLString::equals(currentElement1->getTagName(), TAG_Name))
{
m_Stock->SetName(sym);
}
}
}
}
}
}
std::cout<<m_Stock->ToString();
}
catch( xercesc::XMLException& e )
{
char* message = xercesc::XMLString::transcode( e.getMessage() );
std::ostringstream errBuf;
errBuf << "Error parsing file: " << message << std::flush;
XMLString::release( &message );
}
}
int main(int argc, char** argv){
struct soap *soap = soap_new();
struct _ns1__GetQuote sym;
struct _ns1__GetQuoteResponse quote;
GetXml xml;
std::string response="";
std::string str(argv[1]);
sym.symbol = &str;
soap_init(soap);
//Call the web service
if (soap_call___ns1__GetQuote(soap, NULL, NULL, &sym, quote) == SOAP_OK) {
//std::cout<<"Symbol: "<<*(sym.symbol)<<std::endl<<" Quote: "<<*(quote.GetQuoteResult)<<std::endl;
response = *(quote.GetQuoteResult);
free (quote.GetQuoteResult);
}
else {
std::cout<<"Error in execution of GetQuote:: "<<soap->buf<<std::endl;
return(0);
}
//Parse the SOAP response
xml.readXml(response);
return 0;
}
// Copied from StockQuoteSoap.nsmap file
SOAP_NMAC struct Namespace namespaces[] =
{
{"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://schemas.xmlsoap.org/soap/envelope/", NULL},
{"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://schemas.xmlsoap.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}
};
//stock.hpp
#include <sstream>
class Stock
{
std::string symbol_;
std::string last_;
std::string date_;
std::string time_;
std::string change_;
std::string open_;
std::string high_;
std::string low_;
std::string volume_;
std::string mktcap_;
std::string previousclose_;
std::string percentagechange_;
std::string annrange_;
std::string earns_;
std::string p_e_;
std::string name_;
public:
Stock() {}
Stock(std::string symbol) {symbol_ = symbol;}
void SetSymbol(std::string symbol) {symbol_ = symbol;}
void SetLast(std::string last) {last_ = last;}
void SetDate(std::string date) {date_ = date;}
void SetTime(std::string time) {time_ = time;}
void SetChange(std::string change) {change_ = change;}
void SetOpen(std::string open) {open_ = open;}
void SetHigh(std::string high) {high_ = high;}
void SetLow(std::string low) {low_ = low;}
void SetVolume(std::string volume) {volume_ = volume;}
void SetMktCap(std::string mktcap) {mktcap_ = mktcap;}
void SetPrevClose(std::string previousclose) {previousclose_ = previousclose;}
void SetPercentChange(std::string percentagechange) {percentagechange_ = percentagechange;}
void SetAnnRange(std::string annrange) {annrange_ = annrange;}
void SetEarns(std::string earns) {earns_ = earns;}
void SetPE(std::string p_e) {p_e_ = p_e;}
void SetName(std::string name) {name_ = name;}
//ToString function overridden to display in short format
std::string ToString() const
{
std::stringstream sstr;
sstr << "\'" << symbol_ << "\' Open: " << open_
<< ", Last: " << last_;
return sstr.str();
}
};
//parser.hpp
#include "stock.hpp"
class GetXml
{
public:
GetXml();
~GetXml();
//Function to read the XML string
void readXml(std::string&) throw(std::runtime_error);
private:
xercesc_3_1::XercesDOMParser *m_XmlParser; //DOM Parser pointer
Stock *m_Stock; //To save the returned data
XMLCh* TAG_root;
XMLCh* TAG_Stock;
XMLCh* TAG_Symbol;
XMLCh* TAG_Last;
XMLCh* TAG_Date;
XMLCh* TAG_Time;
XMLCh* TAG_Change;
XMLCh* TAG_Open;
XMLCh* TAG_High;
XMLCh* TAG_Low;
XMLCh* TAG_Volume;
XMLCh* TAG_MktCap;
XMLCh* TAG_PrevClose;
XMLCh* TAG_PercentChange;
XMLCh* TAG_AnnRange;
XMLCh* TAG_Earns;
XMLCh* TAG_PE;
XMLCh* TAG_Name;
};
Location:
Bengaluru, Karnataka, India
- Get link
- X
- Other Apps
Comments
Web services are client and server applications that communicate over the World Wide Web’s (WWW) HyperText Transfer Protocol (HTTP). Web services provide a standard means of inter operating between software applications running on a variety of platforms and frameworks. Web Design Services
ReplyDeleteSOAP Web Services India, Soap Web Services Annotations India
ReplyDeleteThe article provided by you is very nice and it is very helpful to know the more information.keep update with your blogsRuby on rails Online Course
ReplyDelete