首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 串接聚合數據全國天氣預報 API 完整實作範例

     編輯:Java 相關知識

專案背景

本文示範如何使用 Java 串接聚合數據 的「全國天氣預報 API」,包含取得城市列表、依城市名稱/ID 查詢天氣、取得天氣類型代碼對照表等核心功能。適用於需要整合即時氣象資料的應用開發。

API 介紹與準備工作

步驟 1:申請 API Key

步驟 2:理解接口架構

該 API 提供六個子接口,本範例主要使用:

  1. 支援城市列表獲取:取得所有城市 ID 與名稱對照 (第六個子接口)
  2. 根據城市名稱/ID 查詢天氣:核心查詢功能 (第一個子接口)
  3. 天氣種類及圖標列表:天氣代碼對照表 (第四個子接口)

開發策略:先呼叫城市列表接口建立城市名稱與 ID 對照,再依需求查詢特定城市天氣。

核心工具類:網路存取封裝

封裝 HTTP GET/POST 請求,支援參數傳遞與回應處理:

package juheAPI;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

public class PureNetUtil {
    /** GET 請求封裝 */
    public static String get(String url) {
        return post(url, null);
    }

    /** POST 請求核心實作 */
    public static String post(String url, Map param) {
        HttpURLConnection conn = null;
        try {
            URL u = new URL(url);
            conn = (HttpURLConnection) u.openConnection();
            
            if (param != null) {
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                try (OutputStream out = conn.getOutputStream();
                     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out))) {
                    
                    StringBuilder sb = new StringBuilder();
                    for (Map.Entry entry : param.entrySet()) {
                        sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                    }
                    // 移除尾端 '&'
                    writer.write(sb.deleteCharAt(sb.length() - 1).toString());
                }
            }
            
            conn.connect();
            
            if (conn.getResponseCode() == 200) {
                try (InputStream in = conn.getInputStream();
                     BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
                    
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line).append(System.lineSeparator());
                    }
                    // 移除最後換行符
                    String result = sb.toString();
                    return result.substring(0, result.length() - System.lineSeparator().length());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) conn.disconnect();
        }
        return null;
    }
}

功能模組實作

模組一:取得城市列表與 ID 查詢

package juheAPI;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class GetCityList {
    private static final String API_URL = "https://v.juhe.cn/weather/citys?key=YOUR_API_KEY";

    /** 取得完整城市列表原始 JSON */
    public static String execute() {
        return PureNetUtil.get(API_URL);
    }

    /** 根據城市名稱 (支援模糊比對) 取得城市 ID */
    public static String getIDByCityName(String cityName) {
        String result = execute();
        if (result == null) return null;

        JSONObject obj = JSONObject.fromObject(result);
        String resultCode = obj.getString("resultcode");
        
        if ("200".equals(resultCode)) {
            String cityListJson = obj.getString("result");
            JSONArray arr = JSONArray.fromObject(cityListJson);
            
            for (Object o : arr) {
                JSONObject cityObj = JSONObject.fromObject(o.toString());
                // 結構範例:{"id":"2","province":"北京","city":"北京","district":"海淀"}
                String district = cityObj.getString("district");
                
                // 支援完整名稱或包含關係 (如「蘇州」匹配「蘇州市」)
                if (district.equals(cityName) || district.contains(cityName)) {
                    return cityObj.getString("id");
                }
            }
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getIDByCityName("香港"));
    }
}

模組二:依城市查詢即時天氣

package juheAPI;

import net.sf.json.JSONObject;

public class WeatherReportByCity {
    /** 根據城市名稱查詢天氣 (回傳完整 JSON) */
    public static String execute(String cityName) {
        String url = "https://v.juhe.cn/weather/index?cityname=" + cityName 
                   + "&key=YOUR_API_KEY&format=2"; // format=2 回傳 JSON
        return PureNetUtil.get(url);
    }

    /** 解析並取得今日溫度範圍 (如 "8℃~20℃") */
    public static String getTodayTemperatureByCity(String city) {
        String result = execute(city);
        if (result == null) return null;

        JSONObject obj = JSONObject.fromObject(result);
        if ("200".equals(obj.getString("resultcode"))) {
            JSONObject resultObj = JSONObject.fromObject(obj.getString("result"));
            JSONObject todayObj = JSONObject.fromObject(resultObj.getString("today"));
            return todayObj.getString("temperature");
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getTodayTemperatureByCity("蘇州"));
    }
}

模組三:天氣類型代碼對照表

package juheAPI;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class GetWeatherSignAndTypeList {
    private static final String URL = "https://v.juhe.cn/weather/uni?key=YOUR_API_KEY";

    public static String execute() {
        return PureNetUtil.get(URL);
    }

    /** 根據 weather ID (wid) 取得天氣名稱 */
    public static String getWeatherByWid(String wid) {
        String result = execute();
        if (result == null) return null;

        JSONObject obj = JSONObject.fromObject(result);
        if ("200".equals(obj.getString("resultcode"))) {
            JSONArray arr = JSONArray.fromObject(obj.getString("result"));
            for (Object o : arr) {
                JSONObject item = JSONObject.fromObject(o.toString());
                if (item.getString("wid").equals(wid)) {
                    return item.getString("weather");
                }
            }
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getWeatherByWid("10")); // 例:查詢 wid=10 的天氣名稱
    }
}

錯誤碼對照與除錯建議

狀態碼說明處理建議
200請求成功正常解析 result 欄位
201無查詢結果檢查城市名稱拼音/拼寫
202查詢參數錯誤確認 cityname/cityid 格式
203Key 錯誤或餘額不足檢查 API Key 是否正確、額度是否用盡
204請求頻率超限降低呼叫頻率或升級方案

進階應用建議

  • 快取機制:城市列表變動極少,建議啟動時載入並快取至記憶體/Redis,避免重複請求
  • 非同步處理:搭配 CompletableFuture 或 RxJava 實作非同步查詢,提升回應速度
  • 容錯設計:實作重試機制、斷路器模式,應對第三方 API 不穩定情況
  • 資料持久化:將查詢結果存入資料庫,支援歷史天氣趨勢分析
  • 多來源整合:整合中央氣象局、OpenWeatherMap 等多源驗證,提高資料可靠度

依賴庫說明

專案使用 net.sf.json-lib 處理 JSON 解析,Maven 依賴如下:

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>

總結

本範例完整展示了從 API 申請、網路層封裝、JSON 解析到業務邏輯實作的完整流程。採用模組化設計,各功能獨立封裝,便於維護與擴充。實際部署時請務必妥善保管 API Key,並依據業務需求實作適當的快取與容錯機制。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved