【气象助手项目开发】-第三篇:聚合平台WebService技术

一、聚合数据WebService介绍

            聚合数据(https://www.juhe.cn/),是一个专门提供各种数据服务网站。使用之前需要先注册成为开发者。


二、聚合数据WebService服务使用

        1.注册成为聚合数据服务开发者。(如果已有账户,则可跳过此步,直接进入登录界面进行登录)
       
        步骤:
      (1)在浏览器地址框中输入或复制聚合数据官方网址:https://www.juhe.cn/,回车,打开聚合数据网站。
      (2)点击聚合数据网站右上角的注册文本,进入注册界面。




(3)按照界面上的注册向导,完成注册。


(4)使用新注册账户进行登录成功后,方可有权使用聚合数据服务。




2、申请全国天气预报数据API服务(测试使用2个月,之后需要对app进行审核,否则数据服务不能正常使用)
         
         步骤:
(1)初始登录是直接进入个人中心的,可在个人中心申请数据服务,如下图:



(2)如果不是初始登录,则进入首页,可按下图步骤申请全国天气预报数据服务:



(2)点击申请数据按钮,进入申请数据界面。



3)点击申请按钮,完成申请。
          如果是第一次注册,需要输入手机号码,如果是已经申请过此服务,则提醒已经申请过该服务了



3、查看我的数据。
   已经申请过的数据服务,在我的数据界面会以列表的方式一条一条的显示该界面中。

  步骤:
(1)点击左侧数据中心里我的数据,会看到刚刚申请成功的全国天气预报记录,
                可能会有其它申请过的数据服务记录。



(2)点击操作列的查看,可以查看应用信息,尤其AppKey,它作为数据服务识别我们的APP的唯一标识


3)点击操作列的统计,可以查看我们的APP今日和近15天内每小时请求数走势图。

         如果返回的结果下如图,说明申请的数据服务时间上已超过聚合设定的测试模式使用时间,需要实名认证
         后才可继续使用此数据服务。

如需实名认证可进入个人中心,点击个人资料中的实名认证,按要求填写姓名和上传身份证正反面,再点击提交         认 证,完成认证
(一般在一小时内通知认证结果)。   
如果没有以上问题,测试结果应该如下图:



测试结果如下图:


(4)测试其它接口
如果需要用到其它接口,可类似上面两个测试接口的步骤进行测试。

5、编码实现数据的获取

全国天气预报API中有各种语言编写的示例代码,可参考这里的示例完成数据的获取(我选择Java语言)


需要注意的是:如果获取数据时,返回的状态码不是200,可根据API中的错误码对照表查找错误原因。



下面是示例代码中的一些核心代码:

(1)常量工具类:
package com.kedi.juheclient.constant;

/**
 * 常量池对象类:专门用来存放APP中要使用到的常量
 * 
 * @author 张科勇
 *
 */
public class AppConstant {
	// 聚合数据-申请数据服务成功后分配的key,做为此应用与数据服务交互的唯一标识
	public static final String APPKEY = "01360343b6a3ca6d4ade944eee95bf96";
	// 根据城市名获取天气数据的网络地址
	public static final String WEATHER_REPORT_BY_CITY_URL = "http://v.juhe.cn/weather/index";
	// 获取天气种类及标识列表网络地址
	public static final String WEATHER_ICON_AND_ID_URL = "http://v.juhe.cn/weather/uni";
	// 获取支持城市列表网络地址
	public static final String CITY_LIST_URL = "http://v.juhe.cn/weather/citys";
	// 表示数据获取功能
	public static final String RESULT_OK = "200";
}




(2)获取网络数据工具类
package com.kedi.juheclient.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;

/**
 * 网络请求工具类
 * 
 * @author 张科勇
 *
 */
public class NetWorkUtil {
	/**
	 * get方式请求网络数据的方法
	 * 
	 * @param url
	 *            网络地址
	 * @return 网络数据
	 */

	public static <K, V> String get(String url) {
		try {
			// 将字符串网址封装成URL对象,目前是为了使用URL对象打开网络链接
			URL u = new URL(url);
			// 打开网络链接,并强制转化成使用Http协议的链接对象HttpURLConnection
			HttpURLConnection conn = (HttpURLConnection) u.openConnection();
			StringBuffer sb = null;
			conn.setRequestMethod("GET");
			conn.connect();// 建立连接
			// 获取服务端响应码,如果等于200,则服务端响应成功,否则响应不成功
			int recode = conn.getResponseCode();
			// 服务端响应请求成功
			if (recode == HttpsURLConnection.HTTP_OK) {
				// 获取输入流(字节流),读取服务端返回的数据
				InputStream in = conn.getInputStream();
				// 将字节流转化成字符流
				InputStreamReader inr = new InputStreamReader(in);
				// 将低级流封装成高级流
				BufferedReader br = new BufferedReader(inr);
				String str = null;
				sb = new StringBuffer();
				// 按行读取服务端返回的数据,判断如果不为null,则将读到的一行数据保存到StringBuffer中
				while ((str = br.readLine()) != null) {
					sb.append(str);
					// 每行后添加一个换行符
					sb.append(System.getProperty("line.separator"));
				}
				// 关闭输入流
				br.close();
				// 判断如果返回的数据为空,返回null
				if (sb.toString().length() == 0) {
					// 获取的数据为空
					return null;
				}
				// 返回服务端响应的数据字符串(去到最后一行的换行符)
				return sb.toString().substring(0,
						sb.toString().length() - System.getProperty("line.separator").length());
			}
			return null;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * post方式请求网络数据的方法
	 * 
	 * @param url
	 *            网络地址
	 * @param params
	 *            请求参数Map集合,如果没有参数,则传null
	 * @return 返回网络数据
	 */
	public static <K, V> String post(String url, Map<K, V> params) {
		try {
			// 将字符串网址封装成URL对象,目前是为了使用URL对象打开网络链接
			URL u = new URL(url);
			// 打开网络链接,并强制转化成使用Http协议的链接对象HttpURLConnection
			HttpURLConnection conn = (HttpURLConnection) u.openConnection();
			StringBuffer sb = null;
			// 判断网络请求是否带参数,如果带参数则params!=null,接下来需要将参数从Map集合中遍历出来,写到输出流中
			if (params != null) {
				// 打开输出流开闭,默认是关闭的,只有打开后,客户端才可以通过输出流向服务端上传数据(此处上传的是参数数据)
				conn.setDoOutput(true);
				// 设置请求方式为post
				conn.setRequestMethod("POST");
				// 获取输出流对象(字节流)
				OutputStream out = conn.getOutputStream();
				// 将字节流转化成字符流
				OutputStreamWriter ousw = new OutputStreamWriter(out);
				// 将低级流转化成带缓冲的高级流
				BufferedWriter bw = new BufferedWriter(ousw);
				sb = new StringBuffer();
				// 遍历Map集合中的所有参数,并按k=v&的形式保存到StringBuffer中
				for (Map.Entry<K, V> m : params.entrySet()) {
					sb.append(m.getKey() + "=" + m.getValue() + "&");
				}
				// 使用高级流将StringBuffer中的参数写到输出流中
				bw.write(sb.deleteCharAt(sb.length() - 1).toString());
				// 关闭高级输出流,将参数上传给服务端
				bw.close();
				sb = null;
			}
			conn.connect();// 建立连接
			// 获取服务端响应码,如果等于200,则服务端响应成功,否则响应不成功
			int recode = conn.getResponseCode();
			// 服务端响应请求成功
			if (recode == HttpsURLConnection.HTTP_OK) {
				// 获取输入流(字节流),读取服务端返回的数据
				InputStream in = conn.getInputStream();
				// 将字节流转化成字符流
				InputStreamReader inr = new InputStreamReader(in);
				// 将低级流封装成高级流
				BufferedReader br = new BufferedReader(inr);
				String str = null;
				sb = new StringBuffer();
				// 按行读取服务端返回的数据,判断如果不为null,则将读到的一行数据保存到StringBuffer中
				while ((str = br.readLine()) != null) {
					sb.append(str);
					// 每行后添加一个换行符
					sb.append(System.getProperty("line.separator"));
				}
				// 关闭输入流
				br.close();
				// 判断如果返回的数据为空,返回null
				if (sb.toString().length() == 0) {
					// 获取的数据为空
					return null;
				}
				// 返回服务端响应的数据字符串(去到最后一行的换行符)
				return sb.toString().substring(0,
						sb.toString().length() - System.getProperty("line.separator").length());
			}
			return null;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}



(3)获取天气相关数据工具类
package com.kedi.juheclient.utils;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import com.kedi.juheclient.constant.AppConstant;

import android.util.Log;

/**
 * 获取天气相对数据的工具类
 * 
 * @author 张科勇
 *
 */
public class WeatherReportUtil {
	/**
	 * 根据城市名获取天气数据的方法
	 * 
	 * @param cityName
	 *            城市名, 必填
	 * @param dtype
	 *            返回数据格式:json或xml,默认json,可选
	 * @param format
	 *            未来6天预报(future)两种返回格式,1或2,默认1,可选
	 * @return
	 */
	public static String getWeatherReportByCity(String cityName, String dtype, int format) {
		// 接口网址
		String url = AppConstant.WEATHER_REPORT_BY_CITY_URL;
		StringBuffer sb = new StringBuffer();
		String city;
		try {
			// 将传递进来的中文使用UTF-8进行编码
			city = URLEncoder.encode(cityName, "utf-8");
			// 拼装url
			sb.append("cityname=" + city);
			sb.append("&");
			sb.append("format=" + format);
			sb.append("&");
			sb.append("dtype=" + dtype);
			sb.append("&");
			sb.append("key=" + AppConstant.APPKEY);
			url = url + "?" + sb.toString();
			// 这里用get方式请求数据
			String result = NetWorkUtil.get(url);
			JSONObject jsonObj = new JSONObject(result);
			// 安全性检查
			if (!"".equals(jsonObj)) {
				String resultcode = jsonObj.getString("resultcode");
				if (!"".equals(resultcode)) {
					if (AppConstant.RESULT_OK.equals(resultcode)) {
						result = jsonObj.getString("result");
						return result;
					}
				}

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 获取支持的城市列表数据
	 * 
	 * @param dtype
	 *            返回数据格式:json或xml,默认json,可选
	 * @return
	 */
	public static String getCityList(String dtype) {
		// 拼装url
		String url = AppConstant.CITY_LIST_URL;
		Map<String, String> params = new HashMap<String, String>();
		params.put("dtype", dtype);
		params.put("key", AppConstant.APPKEY);
		// 用post方式请求数据
		String result = NetWorkUtil.post(url, params);
		JSONObject jsonObj;
		try {
			jsonObj = new JSONObject(result);
			String resultcode = jsonObj.getString("resultcode");
			if (AppConstant.RESULT_OK.equals(resultcode)) {
				result = jsonObj.getString("result");
				return result;
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取天气种类及标识列表数据
	 * 
	 * @param dtype
	 *            返回数据格式:json或xml,默认json,可选
	 * @return
	 */
	public static String getWeatherIconAndId(String dtype) {
		// 拼装url
		String url = AppConstant.WEATHER_ICON_AND_ID_URL;
		Map<String, String> params = new HashMap<String, String>();
		params.put("dtype", dtype);
		params.put("key", AppConstant.APPKEY);
		// 用post方式请求数据
		String result = NetWorkUtil.post(url, params);
		JSONObject jsonObj;
		try {
			jsonObj = new JSONObject(result);
			String resultcode = jsonObj.getString("resultcode");
			if (AppConstant.RESULT_OK.equals(resultcode)) {
				result = jsonObj.getString("result");
				return result;
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return null;
	}
}


(4)测试代码
package com.kedi.juheclient;

import com.kedi.juheclient.utils.WeatherReportUtil;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
/**
 * 测试类
 * @author 张科勇
 *
 */
public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		new Thread(new Runnable() {

			@Override
			public void run() {
				// 根据城市名获取天气数据
				String weatherStr = WeatherReportUtil.getWeatherReportByCity("北京", "json", 2);
				Log.i("weatherStr=", weatherStr + "");
			}
		}).start();
		new Thread(new Runnable() {

			@Override
			public void run() {

				// 获取天气图标与标识
				String weatherIconAndIdStr = WeatherReportUtil.getWeatherIconAndId("json");
				Log.i("weatherIconAndIdStr=", weatherIconAndIdStr + "");
			}
		}).start();
		new Thread(new Runnable() {

			@Override
			public void run() {
				// 获取支持城市列表数据
				String cityListStr = WeatherReportUtil.getCityList("json");
				Log.i("cityListStr=", cityListStr + "");
			}
		}).start();

	}

}

说明:这是一个Android项目,不要忘了在AndroidManifest.xml文件中添加访问网络的权限。
 
案例源码下载:http://pan.baidu.com/s/1dEjE7Rz



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值