不想浪费了自己写的一个Utility,发布上来,以后可以用
下面是目前找的一些天气WebService的对比较: 只有Webxml那个ok点,但免费的有限:
fhs.6617.com 打不开 http://fhs.6617.com/getweather.asmx?WSDL
www.webxml.com.cn 稳定,免费的有数量及速度限制 250次/24小时 450ms/request
http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl
www.ayandy.com 免费未测试,可以获取数据少
http://www.ayandy.com/Service.asmx?op=getWeatherbyCityName
soft.wopos.com 打不开 http://soft.wopos.com/webservice/weather.asmx
webservice.k-zone.cn 打不开
有了这些数据就可以用接口来写调用了.
下面是自己写的一个Utility,但后来发现不只是一个简单的Utility,老大是要我写一个Webservice天气服务器.不想浪费了这个Utility
里面有缓存的思想(主要解决请求数量限制). 队列请求(主要解决请求速度限制). 自动更新缓存(让缓存有一个过期时限)
package cn.easier.webservice.weather; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import java.util.Set; import org.apache.log4j.Logger; import webxml.WeatherWebServiceStub; import webxml.WeatherWebServiceStub.ArrayOfString; import webxml.WeatherWebServiceStub.GetWeatherbyCityName; import webxml.WeatherWebServiceStub.GetWeatherbyCityNameResponse; /** * 天气接口 * * @author Vange * */ public class WeatherUtils { /** * 数据缓存 */ private static Map<String, Object[]> data = new HashMap<String, Object[]>(); private static Logger logger = Logger.getLogger(WeatherUtils.class); /** * 缓存过期期限,默认为一小时 */ private static long expired = 3600 * 1000; // 1800 seconds, half a // hour /** * 更新所有缓存的间隔,默认为半小时 */ private static long updateCacheInterval = 1800 * 1000; /** * 请求间隔 */ private static int requestInterval = 500; // the interval(millisecond) to // request the // weather server . /** * 请求队列 */ private static Queue<String> queue = new LinkedList<String>(); private static Refresher refresher; static { refresher = new Refresher(); refresher.start(); } /** * 关闭自动更新线程 */ public static void closeAutoRefresh() { logger.info("close auto refresh"); if (refresher != null) { refresher.setStop(true); refresher.interrupt(); } } /** * 获取数据,根据城市名(如广州 ,不要带"市"字) * * @param cityName * @return */ public static WeatherInfo getWeatherByName(String cityName) { logger.debug("want to get data of " + cityName); if (cityName == null) return null; // 读取缓存中数据 if (data.containsKey(cityName)) { // 判断缓存是否已经过期 Object[] cache = data.get(cityName); if (cache != null) { WeatherInfo obj = (WeatherInfo) cache[0]; long lastUpdateTime = (Long) cache[1]; if (obj != null && lastUpdateTime + expired > System .currentTimeMillis()) { return obj; } } logger.debug(cityName + " 's value is not exists"); } else { logger.debug("the key " + cityName + " is not exists"); // 如果没有,直接返回null // 把些请求,加入到请求队列中,和数据字典中 data.put(cityName, null); synchronized (queue) { queue.offer(cityName); } return null; } return null; } /** * 向接口请求天气数据 */ protected static void requestWeatherInfo() { if (queue.isEmpty()) return; String requestCityName = null; synchronized (queue) { requestCityName = queue.poll(); } if (requestCityName == null) return; requestWeatherInfo(requestCityName); } /** * 向接口请求天气数据 并处理对应的数据 * * @param requestCityName */ public static WeatherInfo requestWeatherInfo(String requestCityName) { logger.debug("REAL get info from Server : " + requestCityName); try { WeatherWebServiceStub stub = new WeatherWebServiceStub(); GetWeatherbyCityName cityname = new GetWeatherbyCityName(); cityname.setTheCityName(requestCityName); GetWeatherbyCityNameResponse ret = stub .getWeatherbyCityName(cityname); ArrayOfString cityNameResult = ret.getGetWeatherbyCityNameResult(); if (cityNameResult != null) { // logger.debug("get date : " + cityNameResult); String[] returns = cityNameResult.getString(); if (returns[1] == null || "".equals(returns[1])) { logger.info("requestCityName is NOT supported ! " + requestCityName); // 没有相关数据 return null; } // 读取相关数据 WeatherInfo info = new WeatherInfo(); info.setCityName(returns[1]); info.setDateAndWeather(returns[6]); info.setTemperature(returns[5]); info.setWind(returns[7]); data.put(requestCityName, new Object[] { info, System.currentTimeMillis() }); if (logger.isDebugEnabled()) logger.debug("ADD CACHE :" + requestCityName); return info; } return null; } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage()); } return null; } /** * 请求更新所有缓存 */ protected static void updateAllWeatherInfo() { logger.debug("update all the weather info"); Set<String> keys = data.keySet(); synchronized (queue) { for (String key : keys) { queue.offer(key); } } } /** * 定时刷新器 * * @author Vange * */ private static class Refresher extends Thread { /** * 停止标识 */ private boolean stop = false; private long lastUpdateCache = 0L; @Override public void run() { super.run(); while (true) { try { if (stop) break; // 更新每一个数据 sleep(requestInterval); requestWeatherInfo(); // 更新所有缓存 if (System.currentTimeMillis() > lastUpdateCache + updateCacheInterval) { lastUpdateCache = System.currentTimeMillis(); updateAllWeatherInfo(); } } catch (Exception e) { logger.error(e.getMessage()); } } } /** * 设置结束标识 * * @param b */ public void setStop(boolean b) { this.stop = b; } } }