调用Web Service实现天气预报

随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)

一、概念:Web Service用于消除不同平台、不同语言之间的实现差异,将现有的应用程序发布成开放式服务,从而允许互联网上任何地方、任何平台、任何语言的应用程序来访问该服务。对于Web Service的使用者而言,不管使用何种操作平台、何种编程语言,只要权限允许,都可以调用Web Service,至于Web Service底层是使用什么样的技术实现的对使用者是完全透明的。

二、Web Service特征:

1、自包含性:Web Service是自包含的,Web Service使用者无须安装任何附加软件,只要一种支持Web和XML的编程语言即可;Web Service服务提供者则只需要Web服务器和SOAP服务器。

2、自描述性:Web Service是自描述的,客户端和服务器都无须关心除请求和响应消息的内容和格式之外的任何内容,消息格式与消息内容一起传播,无须外部程序辅助。

2、封装性:Web Service是一种部署在Web应用上的对象,具备良好的封装性。对使用者而言,仅能看到服务描述,而该服务的具体实现、运行平台都是透明的,调用者无须关心,也无法关心。Web Service作为整体提供服务。

3、可编程性:Web Service并不提供图形用户界面,而是提供编程访问的API,Web Service调用者只需知道Web服务器的API接口,即可使用任何平台上的、任何编程语言来调用Web Service。

4、松散耦合:当Web Service的实现发生改变时,调用者无法感受到这种变化。对调用者而言,只要服务实现的接口没有变化,具体实现的改变是完全透明的。

5、高度的平台性:Web Service可以与其他的Web Service进行交互,具有语言和平台无关性,支持CORBA,EJB,DCOM等多种组件标准,支持各种通信协议如:HTTP,SMTP,FTP和RMI等。

6、使用标准协议:Web Service所有的公共协议都使用标准协议描述、传输和交换,这些标准协议在各种平台上完全相同。使用Web Service完全可以在不同供应商之间实现互操作。

7、高度的整合能力:由于Web Service采用简单的、易理解的标准Web协议作为通信协议,完全屏蔽了不同平台的差异,无论CORBA,EJB还是DCOM,都可以通过这种标准的协议进行互操作,实现系统的最高可整合性。

三、优势:

Web Service与其他网络集成技术相比,其优势在于:

1、Web Service使用SOAP作为基本的通信协议,更加简单、易用。

2、Web Service采用已经广泛使用的技术和协议,如XML、HTTP等,因此Web Service更容易掌握。

四、实例:

注:需要引入ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar

下面通过调用http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx站点的提供的Web Service来实现天气预报功能,代码如下:

Activity:

package com.home.activity;

import java.util.ArrayList;
import java.util.List;

import org.ksoap2.serialization.SoapObject;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.home.util.WebServiceUtil;
import com.home.weatherforecast.R;

public class MyWeatherActivity extends Activity {
	// 显示省份的列表
	private Spinner provinceSpinner;
	// 显示城市的列表
	private Spinner citySpinner;
	private TextView todayWeatherText;
	private TextView tomorrowWeatherText;
	private TextView afterdayWeatherText;
	private TextView currentWeatherText;
	private Handler handler;
	// 省份集合
	private List<String> provinces = new ArrayList<String>();
	// 城市集合
	private List<String> cities = new ArrayList<String>();
	private SoapObject detail;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
		handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				if (msg.what == 1) {
					if (provinces != null) {
						ArrayAdapter adapter = new ArrayAdapter(
								MyWeatherActivity.this,
								android.R.layout.simple_dropdown_item_1line,
								provinces);
						// 使用Spinner显示省份列表
						provinceSpinner.setAdapter(adapter);
					} else {
						Toast.makeText(MyWeatherActivity.this, "网络异常",
								Toast.LENGTH_SHORT).show();
					}
				}
				if (msg.what == 2) {
					if (cities != null) {
						ArrayAdapter cityAdapter = new ArrayAdapter(
								MyWeatherActivity.this,
								android.R.layout.simple_dropdown_item_1line,
								cities);
						// 使用Spinner 显示城市列表
						citySpinner.setAdapter(cityAdapter);
					} else {
						Toast.makeText(MyWeatherActivity.this, "网络异常",
								Toast.LENGTH_SHORT).show();
					}
				}
				if (msg.what == 3) {
					String todayWeather = null;
					String tomorrowWeather = null;
					String afterdayWeather = null;
					String currentWeather = null;
					// 获取天气实况
					currentWeather = detail.getProperty(4).toString();
					int index = currentWeather.indexOf(":");
					// 从实况天气中截取出提示信息
					String prompt = currentWeather.substring(0, index + 1);
					// 从实况天气中截取出天气内容
					String content = currentWeather.substring(index + 1);
					String newCurrentWeather = prompt + "\n" + content;
					// 解析今天的天气情况
					String date = detail.getProperty(7).toString();
					todayWeather = "今天:" + date.split(" ")[0];
					todayWeather = todayWeather + "\n天气:" + date.split(" ")[1];
					todayWeather = todayWeather + "\n气温:"
							+ detail.getProperty(8).toString();
					todayWeather = todayWeather + "\n风力:"
							+ detail.getProperty(9).toString() + "\n";
					// 解析明天的天气情况
					date = detail.getProperty(12).toString();
					tomorrowWeather = "明天:" + date.split(" ")[0];
					tomorrowWeather = tomorrowWeather + "\n天气:"
							+ date.split(" ")[1];
					tomorrowWeather = tomorrowWeather + "\n气温:"
							+ detail.getProperty(13).toString();
					tomorrowWeather = tomorrowWeather + "\n风力:"
							+ detail.getProperty(14).toString() + "\n";

					// 解析后天的天气情况
					date = detail.getProperty(17).toString();
					afterdayWeather = "后天:" + date.split(" ")[0];
					afterdayWeather = afterdayWeather + "\n天气:"
							+ date.split(" ")[1];
					afterdayWeather = afterdayWeather + "\n气温:"
							+ detail.getProperty(18).toString();
					afterdayWeather = afterdayWeather + "\n风力:"
							+ detail.getProperty(19).toString() + "\n";
					// 更新当天的天气实况
					currentWeatherText.setText(newCurrentWeather);
					// 更新今天天气
					todayWeatherText.setText(todayWeather);
					// 更新明天天气
					tomorrowWeatherText.setText(tomorrowWeather);
					// 更新后天天气
					afterdayWeatherText.setText(afterdayWeather);
				}
			}
		};
		new Thread() {
			public void run() {
				// 调用远程WebService获取省份列表
				provinces = WebServiceUtil.getProvinceList();
				Message msg = new Message();
				msg.what = 1;
				handler.sendMessage(msg);
			}
		}.start();
		// 当省份Spinner的选择项改变时
		provinceSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				new Thread() {
					public void run() {
						// 调用远程WebService根据省份获取城市列表
						cities = WebServiceUtil
								.getCityListByProvince(provinceSpinner
										.getSelectedItem().toString());
						Message msg = new Message();
						msg.what = 2;
						handler.sendMessage(msg);
					}
				}.start();
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
			}
		});
		// 当城市Spinner的选择项被改变时
		citySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				// 根据城市获取天气信息
				showWeather(citySpinner.getSelectedItem().toString());
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {

			}
		});
	}

	/**
	 * 获取界面组件
	 */
	private void init() {
		todayWeatherText = (TextView) findViewById(R.id.main_tv_weather_today);
		tomorrowWeatherText = (TextView) findViewById(R.id.main_tv_weather_tomorrow);
		afterdayWeatherText = (TextView) findViewById(R.id.main_tv_weather_afterday);
		currentWeatherText = (TextView) findViewById(R.id.main_tv_weather_current);
		provinceSpinner = (Spinner) findViewById(R.id.main_sp_province);
		citySpinner = (Spinner) findViewById(R.id.main_sp_city);
	}

	/**
	 * 根据城市获取天气信息
	 * 
	 * @param city
	 *            城市
	 */
	private void showWeather(final String city) {
		new Thread() {
			public void run() {
				// 获取远程WebService返回的对象
				detail = WebServiceUtil.getWeatherByCity(city);
				Message msg = new Message();
				msg.what = 3;
				handler.sendMessage(msg);
			}
		}.start();
	}
}

访问WebService的工具类(WebServiceUtil):

package com.home.util;

import java.util.ArrayList;
import java.util.List;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

public class WebServiceUtil {
	// 定义WebService的命名空间
	static final String SERVICE_NS = "http://WebXml.com.cn/";
	// 定义WebService提供服务的URL
	static final String SERVICE_URL = "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";

	/**
	 * 调用远程WebService获取省份列表
	 * 
	 * @return List 省份列表
	 */
	public static List<String> getProvinceList() {
		// 调用的方法
		String methodName = "getRegionProvince";
		// 创建HttpTransportSE传输对象
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		// 使用SOAP1.1协议创建Envelope对象
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		// 实例化SoapObject对象
		SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
		// 将SoapObject对象设置为SoapSerializationEnvelope对象的传出SOAP消息
		envelope.bodyOut = soapObject;
		// 设置与.NET提供的WebService保持较好的兼容性
		envelope.dotNet = true;
		try {
			// 调用WebService
			ht.call(SERVICE_NS + methodName, envelope);
			if (envelope.getResponse() != null) {
				// 获取服务器响应返回的SOAP消息
				SoapObject result = (SoapObject) envelope.bodyIn;
				SoapObject detail = (SoapObject) result.getProperty(methodName
						+ "Result");
				// 解析服务器响应的SOAP消息
				return parseProvinceOrCity(detail);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 根据省份获取城市列表
	 * 
	 * @param province
	 * @return List 城市列表
	 */
	public static List<String> getCityListByProvince(String province) {
		// 调用的方法
		String methodName = "getSupportCityString";
		// 创建HttpTransportSE传输对象
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		// 实例化SoapObject对象
		SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
		// 添加一个请求参数
		soapObject.addProperty("theRegionCode", province);
		// 使用SOAP1.1协议创建Envelope对象
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.bodyOut = soapObject;
		// 设置与.NET提供的WebService保持较好的兼容性
		envelope.dotNet = true;
		try {
			// 调用WebService
			ht.call(SERVICE_NS + methodName, envelope);
			if (envelope.getResponse() != null) {
				// 获取服务器响应返回的SOAP消息
				SoapObject result = (SoapObject) envelope.bodyIn;
				SoapObject detail = (SoapObject) result.getProperty(methodName
						+ "Result");
				// 解析服务器响应的SOAP消息
				return parseProvinceOrCity(detail);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解析服务器响应的SOAP消息
	 * 
	 * @param detail
	 *            SOAP消息
	 * @return List
	 */
	private static List<String> parseProvinceOrCity(SoapObject detail) {
		ArrayList<String> result = new ArrayList<String>();
		for (int i = 0; i < detail.getPropertyCount(); i++) {
			// 解析出每个省份
			result.add(detail.getProperty(i).toString().split(",")[0]);
		}
		return result;
	}

	/**
	 * 根据城市获取天气状况
	 * 
	 * @param cityName
	 *            城市名称
	 * @return SoapObject
	 */
	public static SoapObject getWeatherByCity(String cityName) {
		String methodName = "getWeather";
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		SoapObject soapObject = new SoapObject(SERVICE_NS, methodName);
		soapObject.addProperty("theCityCode", cityName);
		envelope.bodyOut = soapObject;
		// 设置与.NET提供的WebService保持较好的兼容性
		envelope.dotNet = true;
		try {
			ht.call(SERVICE_NS + methodName, envelope);
			SoapObject result = (SoapObject) envelope.bodyIn;
			SoapObject detail = (SoapObject) result.getProperty(methodName
					+ "Result");
			return detail;
		} catch (Exception e) {

		}
		return null;
	}
}

布局XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="请选择省份:"
            android:textSize="20dp" />
        <!-- 让用户选择省份的Spinner -->

        <Spinner
            android:id="@+id/main_sp_province"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="请选择城市:"
            android:textSize="20dp" />
        <!-- 让用户选择城市的Spinner -->

        <Spinner
            android:id="@+id/main_sp_city"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <!-- 显示今天天气的文本框 -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/main_tv_weather_today"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <!-- 显示明天天气的文本框 -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/main_tv_weather_tomorrow"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <!-- 显示后天天气的文本框 -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/main_tv_weather_afterday"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <!-- 显示当前天气的文本框 -->

    <TextView
        android:id="@+id/main_tv_weather_current"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

附上图片效果:




 

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
实现天气预报的详细步骤如下: 1. 找到一个可用的天气预报webservice,例如中国气象局提供的天气预报webservice(http://www.webxml.com.cn/WebServices/WeatherWebService.asmx)。 2. 根据webservice的wsdl文件,生成客户端代码。可以使用工具如wsimport(在JDK中自带)或者Axis等。 3. 在HTML中嵌入JavaScript代码,使用XMLHttpRequest对象向webservice发送SOAP请求,获取天气预报数据。可以使用jQuery等JavaScript库简化代码。 4. 解析webservice返回的XML数据,将数据显示在HTML页面上。 下面是一个简单的HTML页面示例,演示如何使用JavaScript调用天气预报webservice并显示结果: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>天气预报</title> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript"> function getWeather() { var city = document.getElementById("city").value; var url = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl"; var soapRequest = '<?xml version="1.0" encoding="utf-8"?>' + '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' + 'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' + 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' + '<soap:Body>' + '<getWeather xmlns="http://WebXml.com.cn/">' + '<theCityCode>' + city + '</theCityCode>' + '<theUserID></theUserID>' + '</getWeather>' + '</soap:Body>' + '</soap:Envelope>'; $.ajax({ type: "POST", url: url, contentType: "text/xml", dataType: "xml", data: soapRequest, success: function (xml) { var weather = $(xml).find("string").text(); document.getElementById("result").innerHTML = weather; } }); } </script> </head> <body> <h1>天气预报</h1> <label for="city">城市:</label> <input type="text" id="city" value="北京"> <button onclick="getWeather()">查询</button> <div id="result"></div> </body> </html> ``` 在上面的代码中,我们使用了jQuery库来简化代码。首先定义一个getWeather函数,当用户点击查询按钮时,该函数会从输入框中获取城市名,然后使用XMLHttpRequest对象向webservice发送SOAP请求,获取天气预报数据。当请求成功后,解析webservice返回的XML数据,将数据显示在HTML页面上。 需要注意的是,由于JavaScript的同源策略限制,我们不能直接在JavaScript中调用跨域的webservice。一种常见的解决方法是使用JSONP或者CORS技术。另外,由于webservice返回的是XML格式的数据,我们需要使用XML解析库(如jQuery)来解析数据。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

u010142437

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值