1. 程式人生 > >VC++ 使用MSSOAP訪問WebService天氣服務(客戶端開發)

VC++ 使用MSSOAP訪問WebService天氣服務(客戶端開發)

操作 new height ati vc++ too all AR tex

緒論

本文介紹使用VC++編程實現訪問天氣Web服務的簡單實例(例子來源於網絡)。

Web天氣服務

http://www.webxml.com.cn/WebServices/WeatherWebService.asmx

天氣預報 Web 服務,數據每2.5小時左右自動更新一次,準確可靠。包括 340 多個中國主要城市和 60 多個國外主要城市三日內的天氣預報數據。

  • getSupportCity

查詢本天氣預報Web Services支持的國內外城市或地區信息

輸入參數:byProvinceName = 指定的洲或國內的省份,若為ALL或空則表示返回全部城市;返回數據:一個一維字符串數組 String(),結構為:城市名稱(城市代碼)。

  • getSupportDataSet

獲得本天氣預報Web Services支持的洲、國內外省份和城市信息

輸入參數:無;返回:DataSet 。DataSet.Tables(0) 為支持的洲和國內省份數據,DataSet.Tables(1) 為支持的國內外城市或地區數據。DataSet.Tables(0).Rows(i).Item("ID") 主鍵對應 DataSet.Tables(1).Rows(i).Item("ZoneID") 外鍵。
Tables(0):ID = ID主鍵,Zone = 支持的洲、省份;Tables(1):ID 主鍵,ZoneID = 對應Tables(0)ID的外鍵,Area = 城市或地區,AreaCode = 城市或地區代碼。

  • getSupportProvince

獲得本天氣預報Web Services支持的洲、國內外省份和城市信息

輸入參數:無; 返回數據:一個一維字符串數組 String(),內容為洲或國內省份的名稱。

  • getWeatherbyCityName

根據城市或地區名稱查詢獲得未來三天內天氣情況、現在的天氣實況、天氣和生活指數

調用方法如下:輸入參數:theCityName = 城市中文名稱(國外城市可用英文)或城市代碼(不輸入默認為上海市),如:上海 或 58367,如有城市名稱重復請使用城市代碼查詢(可通過 getSupportCity 或 getSupportDataSet 獲得);返回數據: 一個一維數組 String(22),共有23個元素。
String(0) 到 String(4):省份,城市,城市代碼,城市圖片名稱,最後更新時間。String(5) 到 String(11):當天的 氣溫,概況,風向和風力,天氣趨勢開始圖片名稱(以下稱:圖標一),天氣趨勢結束圖片名稱(以下稱:圖標二),現在的天氣實況,天氣和生活指數。String(12) 到 String(16):第二天的 氣溫,概況,風向和風力,圖標一,圖標二。String(17) 到 String(21):第三天的 氣溫,概況,風向和風力,圖標一,圖標二。String(22) 被查詢的城市或地區的介紹
下載天氣圖標(包含大、中、小尺寸) 天氣圖例說明 調用此天氣預報Web Services實例下載 (VB ASP.net 2.0)

  • getWeatherbyCityNamePro

根據城市或地區名稱查詢獲得未來三天內天氣情況、現在的天氣實況、天氣和生活指數(For商業用戶)

調用方法同 getWeatherbyCityName,輸入參數:theUserID = 商業用戶ID

Microsoft SOAP Toolkit 3.0

SOAP(簡單對象訪問協議)是交換數據的一種協議規範,是一種輕量的、簡單的、基於XML(標準通用標記語言下的一個子集)的協議,它被設計成在WEB上交換結構化的和固化的信息。

微軟提供了SOAP協議的SDK,SOAP Toolkit3.0是基於COM的一套SOAP開發組件。 Microsoft SOAP Toolkit 3.0 提供一個靈活的框架,可以為各種 Intranet 和 Internet 解決方案構建可伸縮的 Web 服務。

下載安裝:https://www.neowin.net/news/microsoft-soap-toolkit-30

VC++ 訪問WeatherWebService

  基本步驟:

  1.導入類型庫

  2.需要創建一個SoapConnector

  3.下一步創建SoapSerializer

  4.下一步把消息附加到SoapConnector的輸入流

  5.下一步讀取結果.要讀取服務器的回復,客戶端應用需要使用SoapReader,

  6.SoapReader被連接到SoapConnector輸出流

  7.用IXMLDOMElement對象可以從SoapReader裏讀到服務器的回復

附錄:

C++ Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include "WeatherWS.h "

int main(void)
{
CWeatherWS weather;
weather.ConnectInternet();
cout <<
"請輸入城市名(例如-北京):";
string strCityName;
cin >> strCityName;
if (!strCityName.empty())
{
weather.TransMessage(strCityName.c_str());
}
else
{
cout <<
"輸入的城市名為空!" << endl;
}

string wea[
7];
weather.getMessage(wea);
for(int i = 0; i < 7; i++)
{
cout << wea[i] << endl;
}

cin.get();
return 0;
}



// WeatherWS.h : interface for the CWeatherWS class.

//

//////////////////////////////////////////////////////////////////////



#if !defined(AFX_WEATHERWS_H__B1272FDC_06B4_4C5C_8B33_9D4A35AF336C__INCLUDED_)
#define AFX_WEATHERWS_H__B1272FDC_06B4_4C5C_8B33_9D4A35AF336C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <stdio.h>

#import "msxml3.dll" //SOAP使用XML作為其數據格式,因此我們還需要微軟的XML Parser來處理XML內容,它包含在msxml3.dll中。
//using namespace MSXML2; //使用MSXML2的命名空間
#import "C:\\Program Files (x86)\\Common Files\\MSSoap\\Binaries\\MSSOAP30.dll" exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER", "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME") //導入mssoap30.dll
using namespace MSSOAPLib30; //使用MSSOAPLib30的命名空間,需要安裝SOAP Toolkit3.0

#include <string>
#include "windows.h"
#include <iostream>
using namespace std;


class CWeatherWS
{
public:
void ConnectInternet(); //連接網絡
void TransMessage(const char *city); //向網絡發送相應請求
void getMessage(string *weather); //得到需要的信息

CWeatherWS();
virtual ~CWeatherWS();

private:
ISoapSerializerPtr Serializer;
//Serialize指針用於發送SOAP消息
ISoapReaderPtr Reader; //定義讀取指針
ISoapConnectorPtr Connector; //定義連接指針

bool ConnectSuccess;
};

#endif // !defined(AFX_WEATHERWS_H__B1272FDC_06B4_4C5C_8B33_9D4A35AF336C__INCLUDED_)




// WeatherWS.cpp: implementation of the ButterflyWEB class.

//

//////////////////////////////////////////////////////////////////////
#include "WeatherWS.h "
//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

CWeatherWS::CWeatherWS()
{
CoInitialize(
NULL); //COM初始化
}

CWeatherWS::~CWeatherWS()
{
CoUninitialize();
}

void CWeatherWS::ConnectInternet()
{
//創建連接實例
HRESULT hr = Connector.CreateInstance(__uuidof(HttpConnector30));
if(FAILED(hr))
{
cout <<
"CreateInstance ERROR!" << endl;
return;
}

//連接屬性得到將要進行連接的URL
Connector->Property["EndPointURL"] = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx";

//和服務器連接
hr = Connector->Connect();

// Begin message
// Connector->Property["SoapAction"] = _bstr_t(NameSpace)+"/"+_bstr_t(method);
Connector->Property["SoapAction"] = "http://WebXml.com.cn/getWeatherbyCityName"; //將要進行的操作
Connector->BeginMessage(); //開始準備發送消息
}



void CWeatherWS::TransMessage(const char *city)
{
HRESULT hr = Serializer.CreateInstance(
__uuidof(SoapSerializer30));//創建一個Serializer實例
if(!SUCCEEDED(hr))
{
// MessageBox("無法創建DOMDocument對象,請檢查是否安裝了MS XML Parser 運行庫!");
cout << "ERROR";
return ;
}

// 將serializer連接到connector的輸入字符串
Serializer->Init(_variant_t((IUnknown *)Connector->InputStream));

// 創建SOAP消息
Serializer->StartEnvelope("soap", "", "");
Serializer->StartBody(
"body");
Serializer->StartElement(
"getWeatherbyCityName", "http://WebXml.com.cn/", "", ""); // 方法+命名空間
Serializer->StartElement("theCityName", "http://WebXml.com.cn/", "", "");
Serializer->WriteString(city);
//傳入城市的名字
Serializer->EndElement();
Serializer->EndElement();
Serializer->EndBody();
Serializer->EndEnvelope();

try
{
// Send the message to the web service
Connector->EndMessage(); //向網站發送消息
ConnectSuccess = true;
}
catch(_com_error e)
{
MessageBox(
NULL, e.Description(), 0, NULL);
MessageBox(
NULL, "請檢查網絡連接!", "Butterfly Warning", NULL);
ConnectSuccess =
false;
return;
}
}



void CWeatherWS::getMessage(string *weather)
{
if (ConnectSuccess)
{
// 讀取響應
HRESULT hr = Reader.CreateInstance(__uuidof(SoapReader30));
if(!SUCCEEDED(hr))
{
// MessageBox("無法創建DOMDocument對象,請檢查是否安裝了MS XML Parser 運行庫!");
cout << "ERROR";
return ;
}
// 將reader聯接到connector的輸出字符串
Reader->Load(_variant_t((IUnknown *)Connector->OutputStream), "");

string item[
7] = {"省份", "城市", "發布時間", "溫度", "天氣", "風向", "備註"};
string str;

//printf("Answer: %s\n", (const char*)Reader->RpcResult->text);
printf("Answer: %s\n", (const char *)Reader->Body->xml);
string strstr = Reader->Body->xml;
printf(
"\n");

MSXML2::IXMLDOMNodePtr DOMptr = Reader->RpcResult->firstChild;
for(int i = 0, j = 0, k = 0; i < 11; i++)
{
str = (
const char *)DOMptr->firstChild->text;
if (str == "查詢結果為空!")
{
weather[
0] = "對不起" + str;
weather[
2] = "請檢查輸入的信息是否正確!";
return;
}

if (i != 2 && i != 3 && i != 8 && i != 9)
{
//cout<<item[j]<<":"<<str<<endl;
weather[j] = item[k] + ":" + str;
j++;
k++;
}

DOMptr = DOMptr->nextSibling;
//鏈表指針後移
}//輸出信息
// CoUninitialize();

}
}

VC++ 使用MSSOAP訪問WebService天氣服務(客戶端開發)