| Abstract: | XML Web Services is rapidly becoming the technology of choice for distributed application and application-integration, over Internet. The caller application uses the standard protocol (such as HTTP or SMTP) to send specially-formatted XML messages (known as SOAP request envelope); the server application in turn does the processing and sends back the results also as specially formatted XML message (known as SOAP response envelope). The standards-based notion of Web Services enables these two applications; possibly residing on two totally different platforms, and written using varied programming languages and tools; to interact without and platform- or programming language-worries. XML Web Services is receiving more and more vendor and tools support, and the technology itself is maturing rapidly. Microsoft, IBM, and others are working to define the essential layers (such as security, transaction-support, Web Services reliability, coordination and routing) over Web Services. This article illustrates writing XML Web Services client applications in Visual C++, using Microsoft XML Core Services (or MSXML), Microsoft SOAP Toolkit Version 3, and PocketSOAP.
|
| Author: | Darshan Singh (Managing Editor, PerfectXML.com) |
| Last Updated: | February 02, 2003 |
| Download: | CPPSOAP.zip (353 KB ZIP file) |
MSXML, the premier XML processing component from Microsoft, is shipped with various versions of Internet Explorer (for example, IE 6.0 ships MSXML version 3 SP2); and is also available as a separate download from the MSDN Web site. If you are writing a C++ desktop client application and need to call a Web Service, one option is to use the XMLHTTP component inside MSXML.
XMLHTTP, a COM wrapper around WinInet (the core HTTP API used by Internet Explorer), allows sending HTTP GET and POST requests and process the response. XMLHTTP is designed to be used on the client-side, and should not be used inside server applications to send HTTP requests to other servers. If you are writing a server-side application, and need to call a Web Service, refer to example 2 below, which uses ServerXMLHTTP.
This first sample application uses MSXML XMLHTTP to POST a SOAP request to the Weather ?Temperature Web Service on the XMethods Web site.
The header file (XMLHTTP1.h):
#ifndef _XMLHTTP1_H_#define _XMLHTTP1_H_#include <atlbase.h>#import <msxml4.dll> named_guidsusing namespace MSXML2;#define CHECK_HR(hr) { if (FAILED(hr)) { throw -1; } }// SOAP Endpoint URLstatic const TCHAR* const g_lpszSOAPEndpointURL = _T("http://services.xmethods.net:80/soap/servlet/rpcrouter");// SOAP Request to be postedstatic const TCHAR* const g_lpszSOAPReq = _T( "<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' " "xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance' " "xmlns:xsd='http://www.w3.org/1999/XMLSchema'> " "<SOAP-ENV:Body> " "<ns1:getTemp xmlns:ns1='urn:xmethods-Temperature' " " SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'> " "<zipcode xsi:type='xsd:string'>%s</zipcode> " "</ns1:getTemp> " "</SOAP-ENV:Body> " "</SOAP-ENV:Envelope> "); #endif // _XMLHTTP1_H_The source code file (XMLHTTP1.cpp)
#include "stdafx.h"#include "XMLHTTP1.h"//------------------------------------------------------------------------------// Function uses XMLHTTP to POST a SOAP request to the Temprature Web Service// and then uses MSXML DOM to process the SOAP response XML text.//------------------------------------------------------------------------------float CallWebService(LPCTSTR szZipCode){ float fTemprature = -999; USES_CONVERSION; // SOAP Request Envelop to be posted TCHAR szSOAPReq[MAX_PATH*2] = {0}; sprintf(szSOAPReq, g_lpszSOAPReq, szZipCode); //printf(szSOAPReq); // Create an instance of XMLHTTP Class CComPtr<IXMLHTTPRequest> spXMLHTTP; HRESULT hr = spXMLHTTP.CoCreateInstance(CLSID_XMLHTTP40); CHECK_HR(hr); // Initialize the Synchronous HTTP POST request hr = spXMLHTTP->open(_bstr_t(_T("POST")), g_lpszSOAPEndpointURL, VARIANT_FALSE); CHECK_HR(hr); // Set the required Content-Type header hr = spXMLHTTP->setRequestHeader(_bstr_t(_T("Content-Type")), _bstr_t(_T("text/xml"))); CHECK_HR(hr); // Send the POST request, along with the SOAP request envelope text hr = spXMLHTTP->send(_bstr_t(szSOAPReq)); CHECK_HR(hr); if(200 == spXMLHTTP->status) //Success { // using MSXML DOM to process SOAP response XML text CComQIPtr <IXMLDOMDocument2> spResponseXMLDoc; CComPtr <IXMLDOMNode> spResultNode; spResponseXMLDoc = spXMLHTTP->responseXML; spResultNode = spResponseXMLDoc->selectSingleNode(_bstr_t(_T("//return"))); if(spResultNode.p != NULL) { fTemprature = spResultNode->nodeTypedValue; } } else { printf(_T("\nError: %s\n"), W2A(spXMLHTTP->statusText)); } return fTemprature;}// main, The entry point functionint main(int argc, char* argv[]){ if(argc < 2) {//insufficient parameters printf(_T("\nXMLHTTP1.exe: Sample Web Service client to get the temprature for the given Zipcode.\n")); printf(_T("\nUsage:\tXMLHTTP1.exe <US_Zipcode>\nExample: XMLHTTP1.exe 98007\n")); return -1; } try { HRESULT hr = CoInitialize(NULL); CHECK_HR(hr); float fTemp = CallWebService((LPCTSTR)argv[1]); if(fTemp != -999) printf(_T("The temprature at zipcode %s is %.2f Fahrenheit.\nPress Enter to continue..."), argv[1],fTemp); else printf(_T("\nError: Invalid Zipcode or failed to get the temprature at zipcode %s. " "\nPress Enter to continue..."), argv[1]); } catch(int) { //TODO: Error handling printf(_T("Exception raised!")); } CoUninitialize(); getchar(); return 0;}Output:
