使用 HttpURLConnection 发起 GET 请求获取天气数据需设置请求方法、User-Agent 头、超时及 UTF-8 编码,并正确解析 JSON(用 optXXX 防空、处理 weather 数组与 main 嵌套结构),优先通过地理编码转坐标再查询以提升成功率,同时注意 Scanner 输入处理与输入校验。

用 HttpURLConnection 发起 GET 请求获取天气数据
Java 标准库自带的 HttpURLConnection 足够应付小型天气工具的 HTTP 交互,无需引入第三方依赖。关键是正确设置请求头、处理重定向、读取响应流,并注意字符编码。
- 必须显式调用
setRequestMethod("GET"),否则某些 JDK 版本默认为POST - 务必设置
setRequestProperty("User-Agent", "JavaWeatherApp"),否则部分天气 API(如 OpenWeatherMap 免费层)会返回 403 - 响应体要用
InputStreamReader指定"UTF-8"编码,否则中文城市名或天气描述会乱码 - 记得在
finally块中调用conn.disconnect(),避免连接泄漏
URL url = new URL("https://api.openweathermap.org/data/2.5/weather?q=Beijing&appid=YOUR_KEY&units=metric");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent", "JavaWeatherApp");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8")
);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println(response.toString());
}
解析 JSON 响应时避免 org.json 的常见陷阱
OpenWeatherMap 返回的是标准 JSON,用轻量级的 org.json(Maven 坐标:org.json:json:20231013)最省事。但新手常因忽略空值或嵌套结构导致 NullPointerException 或 JSONException。
- 永远用
optString()/optInt()替代getString()/getInt(),前者在字段缺失时返回默认值(null或0),后者直接抛异常 -
weather字段是数组,即使只有一项也要先getJSONArray("weather").getJSONObject(0),不能假设它是个对象 -
main是嵌套对象,需链式调用getJSONObject("main").getDouble("temp"),中间任何一级为空都会崩 - 城市名在
name字段,但部分响应(如拼写错误时)可能没有该字段,必须用optString("name", "Unknown")
把城市名转成经纬度再查天气更可靠
直接用城市名查天气(?q=Shanghai)容易因重名、大小写、空格或翻译差异失败。改用地理编码接口先查坐标,再用 lat/lon 查询,成功率高得多。
- 先请求地理编码 API:
https://api.openweathermap.org/geo/1.0/direct?q=Shanghai&limit=1&appid=YOUR_KEY - 解析返回的 JSON 数组,取第 0 项的
lat和lon字段(用optDouble防空) - 再拼装天气查询 URL:
https://api.openweathermap.org/data/2.5/weather?lat=31.23&lon=121.47&appid=YOUR_KEY&units=metric - 两次请求需分别处理异常和超时,不要合并 try-catch
命令行交互里别用 Scanner.nextLine() 丢掉首行输入
小型工具通常用 Scanner 接收用户输入城市名,但若前面有其他输入(比如菜单选择),容易因残留换行符导致 nextLine() 立即返回空字符串。
立即学习“Java免费学习笔记(深入)”;
- 如果之前用了
nextInt()或next(),务必在调用nextLine()前加一次空的scanner.nextLine()吸收换行符 - 城市名前后空格要
trim(),否则" beijing "会导致 API 返回 404 - 输入为空时应提示重新输入,而不是传给 API——OpenWeatherMap 对空
q=参数返回 400 - 支持输入
quit或exit直接退出循环,避免无限卡住










