【问题标题】:Parsing the openweatherMap json file解析 openweatherMap json 文件
【发布时间】:2019-11-10 01:13:53
【问题描述】:

我正在做一个需要获取天气信息的项目,所以我使用了 openweathermap api。我的程序正常工作,我从“main”和“wind”获取信息,但我还需要从主天气集获取描述。问题是天气集是 json 文件中的列表,我无法转换它映射。我试图解析的示例 json 文件是 http://api.openweathermap.org/data/2.5/weather?q=London

JSON:

{
   "coord":{
      "lon":-0.13,
      "lat":51.51
   },
   "weather":[
      {
         "id":803,
         "main":"Clouds",
         "description":"broken clouds",
         "icon":"04n"
      }
   ],
   "base":"stations",
   "main":{
      "temp":43.56,
      "pressure":1004,
      "humidity":87,
      "temp_min":41,
      "temp_max":46.4
   },
   "visibility":10000,
   "wind":{
      "speed":11.41,
      "deg":80
   },
   "rain":{

   },
   "clouds":{
      "all":75
   },
   "dt":1573350303,
   "sys":{
      "type":1,
      "id":1414,
      "country":"GB",
      "sunrise":1573369754,
      "sunset":1573402780
   },
   "timezone":0,
   "id":2643743,
   "name":"London",
   "cod":200
}

当我们查看文件时,我们注意到天气集中有一个 [] 括号,这在我的项目中造成了问题。我试图查找如何将列表投射到地图并尝试使用我的代码,但没有帮助。文件中的注释代码是我在尝试使其工作时尝试过的东西。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

import com.google.gson.*;
import com.google.gson.reflect.*;
import java.util.List;
import java.lang.reflect.Type; 

import java.util.HashMap;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class PlantWateringApp {

    public static Map<String, Object> jsonToMap(String str) {

        Map<String, Object> map = new Gson().fromJson(str, new TypeToken<HashMap<String, Object>>() {
        }.getType());
        return map;
    }

    public static void main(String[] args) {

        String LOCATION = "delhi,india";
        String result = "{\"coord\":{\"lon\":77.22,\"lat\":28.65},\"weather\":[{\"id\":711,\"main\":\"Smoke\",\"description\":\"smoke\",\"icon\":\"50d\"}],\"base\":\"stations\",\"main\":{\"temp\":72.32,\"pressure\":1015,\"humidity\":59,\"temp_min\":64.4,\"temp_max\":77},\"visibility\":1000,\"wind\":{\"speed\":3.36,\"deg\":270},\"clouds\":{\"all\":0},\"dt\":1573351180,\"sys\":{\"type\":1,\"id\":9165,\"country\":\"IN\",\"sunrise\":1573348168,\"sunset\":1573387234},\"timezone\":19800,\"id\":1273294,\"name\":\"Delhi\",\"cod\":200}";
        System.out.println(result);

        Map<String, Object> respMap = jsonToMap(result.toString());
        Map<String, Object> mainMap = jsonToMap(respMap.get("main").toString());
        Map<String, Object> windMap = jsonToMap(respMap.get("wind").toString());

        // Type listType = new TypeToken<List<Map<String,String>>>()
        // {}.getType();
        // List<Map<String,String>> weatherMap = new
        // Gson().fromJson(respMap.get("description").toString(),listType);

        // Map<String, Object> name = (Map<String, Object>)
        // respMap.get("description");

        // Map<String, Object > weatherMap = jsonToMap
        // (respMap.get("description").toString());

        System.out.println("Location: " + LOCATION);
        System.out.println("Current Temperature: " + mainMap.get("temp"));
        System.out.println("Current Humidity: " + mainMap.get("humidity"));
        System.out.println("Max: " + mainMap.get("temp_min"));
        System.out.println("Min: " + mainMap.get("temp_max"));

        System.out.println("Wind Speed: " + windMap.get("speed"));
        System.out.println("Wind Angle: " + windMap.get("deg"));

    }
}

我尝试使用与 main 和 wind 相同的方式:Map weatherMap = jsonToMap (respMap.get("weather").toString());。但我遇到了错误:

////java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 3 path $[0]

所以我尝试不将 json 转换为 Map,而是直接使用像 Map weatherMap = (Map) respMap.get("weather"); 这样的地图,但我得到了

////java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Map

为此,我尝试将列表投射到地图使用

              List<Map<String,String>> weatherMap = new Gson().fromJson(respMap.get("weather").toString(),listType);

但这说明:

//String cannot be converted to int

我真的很困惑在这种情况下该怎么做。我无法弄清楚如何处理 json 文件中的 []。

【问题讨论】:

标签: java json api


【解决方案1】:

由于此数据以List 的形式提供,您正试图将其转换为Map。那是不对的。您需要将它(天气)作为地图列表,然后需要将每个元素视为地图。这是一个如何将其作为 Map

获取的示例
          ///...
          //// other code
          ///...      
          Map<String, Object > respMap = jsonToMap (result.toString());
          // don't need to convert from string to map again and again
          Map<String, Object > mainMap = (Map<String, Object >)respMap.get("main");
          Map<String, Object > windMap = (Map<String, Object >)respMap.get("wind");

          // fist get weather as list
          List<Map<String, Object >> weather = (List<Map<String, Object>>) (respMap.get("weather"));
            //...

          System.out.println("Wind Speed: " + windMap.get("speed")  );
          System.out.println("Wind Angle: " + windMap.get("deg")  );


          // weather as list
          System.out.println("Weather: "+ weather);

          // assuming weather contains at-least 1 element.
          Map<String, Object> weatherMap = weather.get(0);

          System.out.println("Weather as map: "+ weatherMap);

将其投射到列表中。

          List<Map<String, Object >> weather = (List<Map<String, Object>>) (respMap.get("weather"));

然后将每个元素视为 Map:

// assuming weather contains at-least 1 element.
          Map<String, Object> weatherMap = weather.get(0);

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    让生活变得简单,使用真实的类型。

    import java.util.List;
    
    import com.google.gson.Gson;
    
    public class PlantWateringApp {
    
        class Weather_2_5 {
            List<Weather> weather;
        }
    
        class Weather {
            Integer id;
            String main;
            String description;
            String icon;
        }
    
        public static void main(String[] args) {
    
            String result = "{\"coord\":{\"lon\":77.22,\"lat\":28.65},\"weather\":[{\"id\":711,\"main\":\"Smoke\",\"description\":\"smoke\",\"icon\":\"50d\"}],\"base\":\"stations\",\"main\":{\"temp\":72.32,\"pressure\":1015,\"humidity\":59,\"temp_min\":64.4,\"temp_max\":77},\"visibility\":1000,\"wind\":{\"speed\":3.36,\"deg\":270},\"clouds\":{\"all\":0},\"dt\":1573351180,\"sys\":{\"type\":1,\"id\":9165,\"country\":\"IN\",\"sunrise\":1573348168,\"sunset\":1573387234},\"timezone\":19800,\"id\":1273294,\"name\":\"Delhi\",\"cod\":200}";
            //System.out.println(result);
    
            Gson G = new Gson();
            Weather_2_5 obj = G.fromJson(result, Weather_2_5.class);
    
            for (int idx = 0; idx < obj.weather.size(); idx++) {
                System.out.println(obj.weather.get(idx).description);
            }
        }
    }
    

    【讨论】:

    • 我想你不明白。我正在使用天气 api 来获取任何位置的实时天气。你的程序只是打印 json 文件的元素。
    • 我认为您误读了输出。有2行输出。 1) 调试行 [我刚刚注释掉的] 和 2) obj.weather.get(idx).description 的结果,它只打印“烟雾”。您/可以/将 json 图视为地图,但是当模式发生变化时,您会为自己提供更多的类型和强制转换工作,甚至更多。有关示例,请参见mkyong.com/java/how-to-parse-json-with-gson 第 4 节。
    【解决方案3】:
    猜你喜欢
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2018-10-10
    • 2019-06-09
    相关资源
    最近更新 更多