Using WinInet to call a Web service

来源:互联网 发布:淘宝产品如何排名靠前 编辑:程序博客网 时间:2024/05/18 03:58
Using WinInet to call a Web service
I am working on a MFC/C++ application, and need to call a Web service. I would like to avoid adding any dependency or use any other API (MSXML or SOAP Toolkit), and continue with my application's minimum requirements (which includes Internet Explorer 5.5 or above), and still write the Web service client code. In other words, can you please show me an example of using WinInet to call a Web service? Answer:
Click here to download a sample console application that uses MFC WinInet classes to call a Web service.

MFC provides wrapper classes around WinInet API. These classes simplify the task of writing HTTP/FTP client applications. Following are the eight steps required to send a HTTP request using MFC WinInet classes:
  1. Create an instance of CInternetSession class. This begins an HTTP session.

  2. Call CInternetSession::GetHttpConnection to get an instance of CHttpConnection. Pass the server and HTTP port to this method, and it establishes a connection to an HTTP server.

  3. Open an HTTP request using CHttpConnection::OpenRequest. Pass the rest of the URL (except server name), the HTTP method (GET/POST/...) to this method, and it returns a CHttpFile object.

  4. Optionally, call CHttpFile::AddRequestHeaders to supply any request headers.

  5. Call CHttpFile::SendRequest to actually send the request and get the response back.

  6. Use CHttpFile::QueryInfoStatusCode to find out if the HTTP request succeeded.

  7. On success, use pHttpFile->Read to read the response bytes.

  8. Finally, call CHttpFile::Close and CHttpConnection::Close.
Here is a Web service client code that uses MFC WinInet classes to call Weather - Temperature Web service (written using Apache SOAP) on XMethods.com. This Web service, given a zip code (US only), returns the current temperature.
......#include <afxinet.h>......static const TCHAR* g_lpszSOAPRequest =    _T("<soap:Envelope "    "xmlns:n='urn:xmethods-Temperature' "    "xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' "    "xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' "    "xmlns:xs='http://www.w3.org/2001/XMLSchema' "    "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> "    "<soap:Body soap:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'> "    "  <n:getTemp> "    "     <zipcode xsi:type='xs:string'>98007</zipcode> "    "  </n:getTemp> "   "</soap:Body> ""</soap:Envelope>");#define CHUNK_SIZE      2048   void CallWebService(){   try   {      //   1. Instantiate CInternetSession      CInternetSession httpSession(_T("Sample Web Service Client"),                            1,                           INTERNET_OPEN_TYPE_PRECONFIG,                           NULL,                           NULL,                           INTERNET_FLAG_DONT_CACHE);            //   2. Get CHttpConnection (Server URL and Port required)      CHttpConnection* pHttpConnection =                               httpSession.GetHttpConnection(_T("services.xmethods.net"),                                  INTERNET_FLAG_NO_AUTO_REDIRECT,                                 80, NULL, NULL);      //   3. Open HTTP Request (pass method type [get/post/..] and URL path (except server name))      CHttpFile* pHttpFile             =                               pHttpConnection->OpenRequest                              (_T("POST"),                                  _T("soap/servlet/rpcrouter"),                                  NULL, 1, NULL, NULL,                                  INTERNET_FLAG_KEEP_CONNECTION |                                 INTERNET_FLAG_EXISTING_CONNECT |                                 INTERNET_FLAG_DONT_CACHE |                                 INTERNET_FLAG_RELOAD);      //   4. Add HTTP Request Headers      CString strSOAPReq(g_lpszSOAPRequest);      DWORD dwRewLen = strSOAPReq.GetLength();      CString strHeaders;      strHeaders.Format(_T("Content-Type: text/xml; charset=utf-8/nContent-Length:%d"),          dwRewLen);      pHttpFile->AddRequestHeaders(strHeaders);            //   5. Send the request      pHttpFile->SendRequest(NULL, 0, (LPVOID)(LPCTSTR)strSOAPReq, dwRewLen);      //   6. Check the return HTTP Status Code      DWORD dwStatucCode = HTTP_STATUS_OK;      pHttpFile->QueryInfoStatusCode(dwStatucCode);      if(dwStatucCode == HTTP_STATUS_OK)      {         CString strResponse;         TCHAR szBuf[CHUNK_SIZE] = {0};         UINT nBytesRead;         //   7. Read the response text         do         {            nBytesRead = pHttpFile->Read((void*) szBuf, CHUNK_SIZE);            strResponse += szBuf;            if(nBytesRead < CHUNK_SIZE)               break;         }while(nBytesRead == CHUNK_SIZE);         AfxMessageBox(strResponse);         //TODO: Process the response      }      else      {         //TODO: Error handling      }      //   8. Close the stream/connection      if(pHttpFile)      {         pHttpFile->Close();         delete pHttpFile;         pHttpFile = NULL;      }      if(pHttpConnection)      {         pHttpConnection->Close();         delete pHttpConnection;         pHttpConnection = NULL;      }   }   catch(CInternetException* exp)   {      TCHAR lpszErrorMsg[MAX_PATH+2];      exp->GetErrorMessage(lpszErrorMsg, MAX_PATH);      AfxMessageBox(lpszErrorMsg);   }}......
Click here to download the above sample console application.

原创粉丝点击