[英]Get weather for specific date using Openweather API - parsing JSON response
我正在嘗試使用 Android studio 和 Java 構建一個簡單的天氣預報應用程序。 我按照這里的一些說明( https://www.androdocs.com/java/creating-an-android-weather-app-using-java.html )啟動並運行,這很有效。 但是,我只能得到當前的天氣。 Openweather 預報 API 電話似乎是 5 天。 沒關系,但是我如何獲取用戶指定的未來 5 天內的特定日期的天氣(比如溫度和風速)?
下面是一個示例 JSON 響應(縮短)。 即使我可以在下午 12 點提取特定日期的信息,並獲得該日期的溫度和風速,也足夠了。 如何解析此 JSON 響應以獲取特定日期的溫度和風速? 非常感謝...對不起我是初學者...
{"cod":"200","message":0,"cnt":40,"list":[{"dt":1574283600,"main":{"temp":281.75,"temp_min":281.68, "temp_max":281.75,"壓力":995,"sea_level":995,"grnd_level":980,"濕度":93,"temp_kf":0.07},"天氣":[{"id":501," main":"Rain","description":"中雨","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":4.82,"度":147},"雨":{"3h":5.38},"sys":{"pod":"n"},"dt_txt":"2019-11-20 21:00:00"}, {"dt":1574294400,"main":{"temp":281.79,"temp_min":281.74,"temp_max":281.79,"pressure":995,"sea_level":995,"grnd_level":980,"濕度":91,"temp_kf":0.05},"weather":[{"id":500,"main":"Rain","description":"小雨","icon":"10n"}], "clouds":{"all":100},"wind":{"speed":5.55,"deg":140},"rain":{"3h":1.75},"sys":{"pod" :"n"},"dt_txt":"2019-11-21 00:00:00"},{"dt":1574305200,"main":{"temp":279.48,"temp_min":279.44,"temp_max ":279.48,"壓力":994,"sea_level":994,"grnd_level":980,"濕度":95,"temp_kf":0.04},"天氣":[{"id":500,"main" :"Rain","description":"小雨","icon":"10n"}],"clouds":{"all":100}, "風":{"速度":2.37,"deg":155},"雨":{"3h":0.94},"sys":{"pod":"n"},"dt_txt":"2019 -11-21 03:00:00"},{"dt":1574316000,"main":{"temp":278.56,"temp_min":278.54,"temp_max":278.56,"pressure":995,"sea_level ":995,"grnd_level":980,"濕度":94,"temp_kf":0.02},"weather":[{"id":500,"main":"Rain","description":"小雨","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":1.73,"deg":128},"rain":{"3h" :0.06},"sys":{"pod":"n"},"dt_txt":"2019-11-21 06:00:00"},{"dt":1574326800,"main":{"temp ":279.19,"temp_min":279.19,"temp_max":279.19,"壓力":995,"sea_level":995,"grnd_level":981,"濕度":95,"temp_kf":0},"天氣" :[{"id":804,"main":"Clouds","description":"陰雲","icon":"04d"}],"clouds":{"all":100},"wind ":{"speed":1.79,"deg":104},"sys":{"pod":"d"},"dt_txt":"2019-11-21 09:00:00"},{" dt":1574337600,"main":{"temp":282.2,"temp_min":282.2,"temp_max":282.2,"pressure":995,"sea_level":995,"grnd_level":980,"濕度": 85,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"小雨"," icon":"10d"}],"clouds":{"all":100},"wind":{"speed":2.78,"deg":129},"rain":{"3h":0.19} ,"sys":{"pod":"d"},"dt_txt":"2019-11-21 12:00:00"}
這是一個使用JSON-Simple庫解析從OpenWeatherMap.org下載的 JSON 數據的示例應用程序。
package work.basil.example;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Weather
{
public static void main ( String[] args )
{
Weather app = new Weather();
app.demo();
}
private void demo ( )
{
//Creating a JSONParser object
JSONParser jsonParser = new JSONParser();
try
{
// Download JSON.
String yourKey = "b6907d289e10d714a6e88b30761fae22";
URL url = new URL( "https://samples.openweathermap.org/data/2.5/forecast/hourly?zip=79843&appid=b6907d289e10d714a6e88b30761fae22" + yourKey ); // 79843 = US postal Zip Code for Marfa, Texas.
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
// Parse JSON
JSONObject jsonObject = ( JSONObject ) jsonParser.parse( reader );
System.out.println( "jsonObject = " + jsonObject );
JSONArray list = ( JSONArray ) jsonObject.get( "list" );
System.out.println( "list = " + list );
// Loop through each item
for ( Object o : list )
{
JSONObject forecast = ( JSONObject ) o;
Long dt = ( Long ) forecast.get( "dt" ); // Parse text into a number of whole seconds.
Instant instant = Instant.ofEpochSecond( dt ); // Parse the count of whole seconds since 1970-01-01T00:00Z into a `Instant` object, representing a moment in UTC with a resolution of nanoseconds.
ZoneId z = ZoneId.of( "America/Chicago" ); // Specify a time zone using a real `Continent/Region` time zone name. Never use 2-4 letter pseudo-zones such as `PDT`, `CST`, `IST`, etc.
ZonedDateTime zdt = instant.atZone( z ); // Adjust from a moment in UTC to the wall-clock used by the people of a particular region (a time zone). Same moment, same point on the timeline, different wall-clock time.
LocalTime lt = zdt.toLocalTime() ;
// … compare with lt.equals( LocalTime.NOON ) to find the data sample you desire.
System.out.println( "dt : " + dt );
System.out.println( "instant : " + instant );
System.out.println( "zdt : " + zdt );
JSONObject main = ( JSONObject ) forecast.get( "main" );
System.out.println( "main = " + main );
Double temp = ( Double ) main.get( "temp" ); // Better to use BigDecimal instead of Double for accuracy. But I do not know how to get the JSON-Simple library to parse the original string input as a BigDecimal.
System.out.println( "temp = " + temp );
JSONObject wind = ( JSONObject ) forecast.get( "wind" );
System.out.println( "wind = " + wind );
System.out.println( "BASIL - wind.getCLass: " + wind.getClass() );
Double speed = ( Double ) wind.get( "speed" );
System.out.println( "speed = " + speed );
System.out.println( "\n" );
}
}
catch ( FileNotFoundException e )
{
e.printStackTrace();
}
catch ( IOException e )
{
e.printStackTrace();
}
catch ( ParseException e )
{
e.printStackTrace();
}
}
}
請注意,當遇到缺少小數點分隔符的風速數據點時,此代碼會崩潰。 例如,該數據的發布者應該寫入1.0
而不是1
以保持一致性。 如果他們這樣做了,庫會將1.0
解析為Double
而不是將1
解析為Long
。
此代碼還使用 JSON-Simple 的原始版本 1,現已失效。 這個項目是分叉的,產生了截然不同的版本 2 和 3。
請參閱此頁面使用 JSON-Simple (Java) 在 JSON 數據中解析十進制數字,其中一些缺少小數分隔符,以獲取有關解析十進制問題和分叉項目鏈接的詳細信息。
因此,雖然我不建議將此代碼用於生產用途,但它可能會對您有所幫助。 對於實際工作,請考慮 JSON-Simple 的更高版本 3 或可用於 Java 的其他幾個 JSON 處理庫中的任何一個。
請參閱此 URL中的示例數據。 要使其可讀,請使用您的文本編輯器或IDE重新格式化 JSON 數據。
樣品 output:
dt : 1553709600
instant : 2019-03-27T18:00:00Z
zdt : 2019-03-27T13:00-05:00[America/Chicago]
main = {"temp":286.44,"temp_min":286.258,"grnd_level":1002.193,"temp_kf":0.18,"humidity":100,"pressure":1015.82,"sea_level":1015.82,"temp_max":286.44}
temp = 286.44
wind = {"deg":202.816,"speed":5.51}
speed = 5.51
dt : 1553713200
instant : 2019-03-27T19:00:00Z
zdt : 2019-03-27T14:00-05:00[America/Chicago]
main = {"temp":286.43,"temp_min":286.3,"grnd_level":1002.667,"temp_kf":0.13,"humidity":100,"pressure":1016.183,"sea_level":1016.183,"temp_max":286.43}
temp = 286.43
wind = {"deg":206.141,"speed":4.84}
speed = 4.84
You can serialize the response JSON string to POJOs by any one of the most popular JSON libraries such as Jackson
or Gson
, then retrieve fields you want of the object whose date field equals given date. 順便說一句,您的 JSON 字符串無效,末尾缺少]}
。
POJO
@JsonIgnoreProperties(ignoreUnknown = true)
class Response {
List<Weather> list;
//general getters and setters
}
@JsonIgnoreProperties(ignoreUnknown = true)
class Weather {
JsonNode main;
JsonNode wind;
@JsonProperty("dt_txt")
String dtTxt;
//general getters and setters
}
使用@JsonIgnoreProperties
(由Jackson 提供)忽略序列化時您不關心的那些字段。
代碼片段
ObjectMapper mapper = new ObjectMapper();
Response response = mapper.readValue(jsonStr, Response.class);
String givenDate = "2019-11-21 12:00:00";
response.getList().forEach(e -> {
if (givenDate.equals(e.getDtTxt())) {
System.out.println("temp: " + e.getMain().get("temp").asText());
System.out.println("wind speed:" + e.getWind().get("speed").asText());
}
});
控制台 output
溫度:282.2
風速:2.78
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.