You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将JSON转换为HashMap时出现NullPointerException,求技术解决方案

问题分析与修复方案

看起来你在使用Gson解析OpenWeatherMap的JSON数据时遇到了不少麻烦,NullPointerException和JSON解析异常的根源主要有三个方面:URL格式错误、对API返回结构理解有误,还有不正确的Gson使用方式。我来帮你一步步修复这些问题:

核心问题拆解

  • URL参数格式错误:你代码里用了&来分隔URL参数,这是HTML转义字符,直接放在URL里会导致OpenWeatherMap API无法正确识别参数,返回的可能不是有效的JSON数据(甚至是错误页面),后续解析自然会出问题。
  • API返回结构误解:OpenWeatherMap的forecast(5天预报)接口返回的JSON结构中,main和wind并不是直接在根对象里的,它们嵌套在list数组的每一个元素中。你直接调用respMap.get("main")会得到null,再调用null.toString()就触发了NullPointerException。
  • 错误的对象转Map方式:就算拿到了正确的嵌套对象,先调用toString()再传入jsonToMap是错误的——Gson解析后的Map对象调用toString()得到的不是标准JSON格式,再次解析会抛出异常。正确的做法是直接将嵌套的Object强制转换为Map<String, Object>。

修复后的完整代码

import java.util.HashMap;
import java.net.*;
import java.io.*;
import java.util.List;
import java.util.Map;
import com.google.gson.*;
import com.google.gson.reflect.*;

public class Weather {
    private static Map<String, Object> jsonToMap(String str){
        return new Gson().fromJson(str, new TypeToken<HashMap<String, Object>>() {}.getType());
    }

    public static void main(String[] args){
        String apiKey = "YOUR_ACTUAL_API_KEY"; // 替换成你的OpenWeatherMap API密钥
        // 修正URL中的参数分隔符:把&amp;换成&
        String urlString = "http://api.openweathermap.org/data/2.5/forecast?id=1174872&APPID=" + apiKey + "&units=metric";
        
        try{
            StringBuilder result = new StringBuilder();
            URL url = new URL(urlString);
            URLConnection connection = url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            reader.close();
            
            System.out.println("json print: ");
            System.out.println(result);
            
            // 解析根对象
            Map<String, Object> respMap = jsonToMap(result.toString());
            
            // 获取list数组(forecast接口返回的是多个时段的预报数据)
            List<Map<String, Object>> forecastList = (List<Map<String, Object>>) respMap.get("list");
            if (forecastList == null || forecastList.isEmpty()) {
                System.out.println("No forecast data available");
                return;
            }
            
            // 取第一个时段的预报数据(最近的预报)
            Map<String, Object> firstForecast = forecastList.get(0);
            
            // 直接将嵌套的main和wind转换为Map,不需要转String
            Map<String, Object> mainMap = (Map<String, Object>) firstForecast.get("main");
            Map<String, Object> windMap = (Map<String, Object>) firstForecast.get("wind");
            
            // 输出数据,先判空避免NPE
            if (mainMap != null) {
                System.out.println("Current Temperature: " + mainMap.get("temp"));
                System.out.println("Current Humidity: " + mainMap.get("humidity"));
            }
            if (windMap != null) {
                System.out.println("Current Wind Speed: " + windMap.get("speed"));
                System.out.println("Current Wind Direction : " + windMap.get("deg"));
            }
            
        }catch(NullPointerException e){
            System.out.println("Null Pointer Exception Occurred!");
            e.printStackTrace(); // 打印堆栈信息,方便排查具体哪里出问题
        }catch (IOException e) {
            System.out.println("Input Output Exception Occurred!");
            e.printStackTrace();
        }
    }
}

额外提示

  1. 记得把代码里的YOUR_ACTUAL_API_KEY替换成你从OpenWeatherMap获取的有效API密钥。
  2. 添加了e.printStackTrace()可以帮助你更精准地定位异常发生的位置,方便后续调试。
  3. 增加了判空逻辑,避免因为API返回结构变化或者数据缺失导致的NPE。

内容的提问来源于stack exchange,提问作者FallenGodfather

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:24:45