1. 程式人生 > 其它 >呼叫第三方Api獲取天氣資訊

呼叫第三方Api獲取天氣資訊

根據ip獲取城市資訊

  • 導包
<!--IP地址解析-->
<dependency>
    <groupId>org.lionsoul</groupId>
    <artifactId>ip2region</artifactId>
    <version>1.7.2</version>
</dependency>
<!--json字串解析-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.72</version>
</dependency>
  • 下載依賴庫 ip2region.db

https://gitee.com/lionsoul/ip2region/tree/master/data

下載解壓後只需要 data 目錄下的 ip2region.db

ip2region.db 可以複製到 resources 目錄下( maven 專案)

  • 獲取城市資訊
//獲取ip所在地址
    public static String getAddressByIp(String ip) {
        try {
            //db
            URL url = ip2regionTest.class.getClassLoader().getResource("ip2region.db");
            String dbPath = url.getFile();
            File file = new File(url.getFile());
            if (file.exists() == false) {
                System.out.println("Error: Invalid ip2region.db file");
            }
 
            //查詢演算法
            int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree
            //int algorithm = DbSearcher.BINARY_ALGORITHM; //Binary
            //int algorithm = DbSearcher.MEMORY_ALGORITYM; //Memory
            DbConfig config = new DbConfig();
            DbSearcher searcher = new DbSearcher(config, dbPath);
            //define the method
            Method method = null;
            switch (algorithm) {
                case DbSearcher.BTREE_ALGORITHM:
                    method = searcher.getClass().getMethod("btreeSearch", String.class);
                    break;
                case DbSearcher.BINARY_ALGORITHM:
                    method = searcher.getClass().getMethod("binarySearch", String.class);
                    break;
                case DbSearcher.MEMORY_ALGORITYM:
                    method = searcher.getClass().getMethod("memorySearch", String.class);
                    break;
            }
            DataBlock dataBlock = null;
            if (Util.isIpAddress(ip) == false) {
                System.out.println("Error: Invalid ip address");
            }
            dataBlock = (DataBlock) method.invoke(searcher, ip);
            //address格式:中國|0|廣東省|深圳市|電信
            String address = dataBlock.getRegion();
            //下兩行 防止擷取報錯 在本方法catch
            String[] splitIpString = address.split("\\|");
            String succ = splitIpString[4];
            return address;
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

// 測試
public static void main(String[] args) {
        String addressByIp = getAddressByIp("14.215.177.38");
        System.out.println(addressByIp);
}

效果

根據城市資訊獲取天氣資訊

免費的Api介面

國國家氣象局

http://www.weather.com.cn/data/sk/101010100.html
http://www.weather.com.cn/data/cityinfo/101010100.html

注意:

上面url中的“101010100”是城市程式碼,這裡指代“北京”的城市程式碼。只需要改變城市程式碼,就可以得到所在城市的天氣資訊。

萬年曆 (支援未來幾天預告)

http://wthrcdn.etouch.cn/weather_mini?city=北京
http://www.sojson.com/open/api/weather/json.shtml?city=北京

第二個Api介面變化請到

http://www.sojson.com/api/weather.html 檢視詳情

  • 使用

天氣實體類

public class WeatherInfo {
    private String date;        //時間
    private String week;        //星期
    private String lunar;       //農曆時間
    private String cityname;    //城市名
    private String weather;     //天氣
    private String temp;        //當前溫度
    private String highTemp;    //最低溫度
    private String lowTemp;     //當前溫度
    private String tips;        //小提示
 
    ... (省略get,set,toString方法)
 
}
  • 天氣獲取工具類
package com.cqdpark.modules.generator.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqdpark.modules.generator.vo.WeatherInfoVO;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.zip.GZIPInputStream;

/**
 * 天氣工具類
 *
 * @author zhangliang
 * @date 2022-04-18 17:47
 */
public class WeatherUtils {
    private static String weatherUrl = "http://wthrcdn.etouch.cn/weather_mini?city=";
    /**
     * 通過城市名稱獲取該城市的天氣資訊
     */
    public static String GetWeatherData(String cityname) {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = null;
        try {
            URL url = new URL(weatherUrl + cityname);
            URLConnection conn = url.openConnection();
            InputStream is = conn.getInputStream();
            GZIPInputStream gzin = new GZIPInputStream(is);
            // 設定讀取流的編碼格式,自定義編碼
            InputStreamReader isr = new InputStreamReader(gzin, "utf-8");
            reader = new BufferedReader(isr);
            String line = null;
            while((line = reader.readLine()) != null){
                sb.append(line + " ");
            }
            reader.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * 將JSON格式資料進行解析 ,返回一個weather物件
     */
    public static WeatherInfoVO GetWeather(String weatherInfobyJson){
        JSONObject dataOfJson = JSONObject.parseObject(weatherInfobyJson);   // json天氣資料
        if(dataOfJson.getIntValue("status") != 1000){
            return null;
        }
        // 建立WeatherInfo物件,提取所需的天氣資訊
        WeatherInfoVO weatherInfo = new WeatherInfoVO();

        // 獲取當前日期:日期、星期
        Calendar cal = Calendar.getInstance();    							     // Calendar類的例項化
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日");  // 時間的格式化
        weatherInfo.setDate(sdf1.format(cal.getTime()));                // 時間
        SimpleDateFormat sdf2 = new SimpleDateFormat("EEEE");
        weatherInfo.setWeek(sdf2.format(cal.getTime()));                // 星期

        // 從json資料中提取資料:城市、溫度、小提醒
        dataOfJson = JSONObject.parseObject(dataOfJson.getString("data"));
        weatherInfo.setCityname(dataOfJson.getString("city"));            // 城市
        weatherInfo.setTemp(dataOfJson.getString("wendu"));               // 溫度
        weatherInfo.setTips(dataOfJson.getString("ganmao"));              // 小提示

        // 獲取今天的天氣預報資訊:最高溫度、最低溫度、天氣
        JSONArray forecast = dataOfJson.getJSONArray("forecast");
        JSONObject result = forecast.getJSONObject(0);
        weatherInfo.setHighTemp(result.getString("high").substring(2));   // 最高氣溫
        weatherInfo.setLowTemp(result.getString("low").substring(2));     // 最低氣溫
        weatherInfo.setWeather(result.getString("type"));                 // 天氣

        return weatherInfo;
    }

}

  • 測試
public class Test {
 
    public static void main(String[] args){
        String info = WeatherUtils.GetWeatherData("天津");
        System.out.println("1.預測結果:" + info);                    // 全部天氣資料,含預測
        WeatherInfo weatherinfo = WeatherUtils.GetWeather(info);
        System.out.println("2.今天天氣:" + weatherinfo.toString());  // 當天天氣資料
    }
 
}
  • 結果

預測結果

{undefined
    "data": {undefined
        "yesterday": {undefined
            "date": "9日星期一",
            "high": "高溫 8℃",
            "fx": "東北風",
            "low": "低溫 1℃",
            "fl": "<![CDATA[4-5級]]>",
            "type": "小雨"
        },
        "city": "天津",
        "forecast": [
            {undefined
                "date": "10日星期二",
                "high": "高溫 13℃",
                "fengli": "<![CDATA[4-5級]]>",
                "low": "低溫 3℃",
                "fengxiang": "西北風",
                "type": "晴"
            },
            {undefined
                "date": "11日星期三",
                "high": "高溫 16℃",
                "fengli": "<![CDATA[4-5級]]>",
                "low": "低溫 4℃",
                "fengxiang": "西南風",
                "type": "晴"
            },
            {undefined
                "date": "12日星期四",
                "high": "高溫 16℃",
                "fengli": "<![CDATA[4-5級]]>",
                "low": "低溫 2℃",
                "fengxiang": "東北風",
                "type": "多雲"
            },
            {undefined
                "date": "13日星期五",
                "high": "高溫 8℃",
                "fengli": "<![CDATA[3-4級]]>",
                "low": "低溫 0℃",
                "fengxiang": "北風",
                "type": "多雲"
            },
            {undefined
                "date": "14日星期六",
                "high": "高溫 10℃",
                "fengli": "<![CDATA[4-5級]]>",
                "low": "低溫 2℃",
                "fengxiang": "西北風",
                "type": "晴"
            }
        ],
        "ganmao": "天冷風大且晝夜溫差也很大,易發生感冒,請注意適當增減衣服。",
        "wendu": "9"
    },
    "status": 1000,
    "desc": "OK"
}

今天天氣

WeatherInfo{date='2020年03月10日', week=星期二, lunar='null', cityname='天津', weather='晴', temp='9', highTemp=' 13℃', lowTemp=' 3℃', tips='天冷風大且晝夜溫差也很大,易發生感冒,請注意適當增減衣服。'}

預測結果:是該API獲取的全部資料,包含昨天,今天,以及未來4天的天氣情況;
今天天氣:是從預測結果JSON資料中取出來,封裝成物件的資料,在data.forecast下的第一條記錄中。


參考連結:
https://blog.csdn.net/zhiwenganyong/article/details/122755057
https://blog.csdn.net/weixin_44259720/article/details/104768288