package test;
import java.net.*;
import java.io.*;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;
public class TestGson {
URL callToApi;
//------------------------------------------------------------------------------
public static void main(String[] args) {
new TestGson();
}
//------------------------------------------------------------------------------
public TestGson(){
try{
sendCallToApi();
readJson();
}catch(IOException e){
e.printStackTrace();
}
}
//------------------------------------------------------------------------------
public void sendCallToApi(){
try{
callToApi = new URL("http://api.wunderground.com/api" +
"/[insert key here]" +
"/geolookup/conditions/forecast/q/" +
"Australia/" +
"Sydney.json");
}catch(MalformedURLException e){
e.printStackTrace();
}
}
//------------------------------------------------------------------------------
public void readJson() throws IOException{
Gson g = new Gson();
InputStreamReader in = new InputStreamReader(callToApi.openStream());
BufferedReader reader = new BufferedReader(in);
String message = "hello";
StringBuffer buf = new StringBuffer();
while(message!=null){
message = reader.readLine();
buf.append(message);
}
message = buf.toString();
String wdf = g.fromJson(message, String.class);
System.out.println(wdf);
}
//------------------------------------------------------------------------------
}
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2
at com.google.gson.Gson.fromJson(Gson.java:806)
at com.google.gson.Gson.fromJson(Gson.java:761)
at com.google.gson.Gson.fromJson(Gson.java:710)
at com.google.gson.Gson.fromJson(Gson.java:682)
at test.TestGson.readJson(TestGson.java:49)
at test.TestGson.<init>(TestGson.java:19)
at test.TestGson.main(TestGson.java:13)
Caused by: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2
at com.google.gson.stream.JsonReader.nextString(JsonReader.java:464)
at com.google.gson.internal.bind.TypeAdapters$13.read(TypeAdapters.java:349)
at com.google.gson.internal.bind.TypeAdapters$13.read(TypeAdapters.java:337)
at com.google.gson.Gson.fromJson(Gson.java:795)
... 6 more
导致这些错误的原因是什么?如何正确调用Weather Underground API以接收天气信息?
我通过修改Mykong.com上给出的示例尝试了这一点。
来自Weather Underground的{ "response": { "version": "0.1" ,"termsofService": "http://www.wunderground.com/weather/api/d/terms.html" ,"features": { "geolookup": 1 , "conditions": 1 , "forecast": 1 } } , "location": { "type":"INTLCITY", "country":"SD", "country_iso3166":"SA", "country_name":"Saudi Arabia", "state":"", "city":"Jeddah", "tz_short":"AST", "tz_long":"Asia/Riyadh", "lat":"21.67000008", "lon":"39.15000153", "zip":"00000", "magic":"1", "wmo":"41024", "l":"/q/zmw:00000.1.41024", "requesturl":"global/stations/41024.html", "wuiurl":"http://www.wunderground.com/global/stations/41024.html", "nearby_weather_stations": { "airport": { "station": [ { "city":"Jeddah King Abdul Aziz International Airport", "state":"", "country":"Saudi Arabia", "icao":"OEJN", "lat":"21.70000076", "lon":"39.18333435" }, { "city":"Jeddah", "state":"", "country":"SD", "icao":"OEJN", "lat":"21.67000008", "lon":"39.15000153" }, { "city":"Makkah", "state":"", "country":"SD", "icao":"OEMK", "lat":"21.43000031", "lon":"39.77000046" } ] } , "pws": { "station": [ ] } } } , "current_observation": { "image": { "url":"http://icons-ak.wxug.com/graphics/wu2/logo_130x80.png", "title":"Weather Underground", "link":"http://www.wunderground.com" }, "display_location": { "full":"Jeddah, Saudi Arabia", "city":"Jeddah", "state":"", "state_name":"Saudi Arabia", "country":"SD", "country_iso3166":"SA", "zip":"00000", "latitude":"21.67000008", "longitude":"39.15000153", "elevation":"12.00000000" }, "observation_location": { "full":"Jeddah, ", "city":"Jeddah", "state":"", "country":"SD", "country_iso3166":"SA", "latitude":"21.67000008", "longitude":"39.15000153", "elevation":"39 ft" }, "estimated": { }, "station_id":"OEJN", "observation_time":"Last Updated on February 12, 9:00 AM AST", "observation_time_rfc822":"Tue, 12 Feb 2013 09:00:00 +0300", "observation_epoch":"1360648800", "local_time_rfc822":"Tue, 12 Feb 2013 09:08:53 +0300", "local_epoch":"1360649333", "local_tz_short":"AST", "local_tz_long":"Asia/Riyadh", "local_tz_offset":"+0300", "weather":"Clear", "temperature_string":"77 F (25 C)", "temp_f":77, "temp_c":25, "relative_humidity":"57%", "wind_string":"From the North at 10 MPH", "wind_dir":"North", "wind_degrees":10, "wind_mph":10, "wind_gust_mph":0, "wind_kph":17, "wind_gust_kph":0, "pressure_mb":"1011", "pressure_in":"29.86", "pressure_trend":"0", "dewpoint_string":"61 F (16 C)", "dewpoint_f":61, "dewpoint_c":16, "heat_index_string":"NA", "heat_index_f":"NA", "heat_index_c":"NA", "windchill_string":"NA", "windchill_f":"NA", "windchill_c":"NA", "feelslike_string":"77 F (25 C)", "feelslike_f":"77", "feelslike_c":"25", "visibility_mi":"N/A", "visibility_km":"N/A", "solarradiation":"", "UV":"-1", "precip_1hr_string":"-9999.00 in (-9999.00 mm)", "precip_1hr_in":"-9999.00", "precip_1hr_metric":"-9999.00", "precip_today_string":"0.00 in (0.0 mm)", "precip_today_in":"0.00", "precip_today_metric":"0.0", "icon":"clear", "icon_url":"http://icons-ak.wxug.com/i/c/k/clear.gif", "forecast_url":"http://www.wunderground.com/global/stations/41024.html", "history_url":"http://www.wunderground.com/history/airport/OEJN/2013/2/12/DailyHistory.html", "ob_url":"http://www.wunderground.com/cgi-bin/findweather/getForecast?query=21.67000008,39.15000153" } , "forecast":{ "txt_forecast": { "date":"3:00 AM AST", "forecastday": [ { "period":0, "icon":"partlycloudy", "icon_url":"http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", "title":"Tuesday", "fcttext":"Clear in the morning, then partly cloudy. High of 84F. Breezy. Winds from the NNW at 10 to 20 mph.", "fcttext_metric":"Clear in the morning, then partly cloudy. High of 29C. Breezy. Winds from the NNW at 15 to 30 km/h.", "pop":"0" } , { "period":1, "icon":"clear", "icon_url":"http://icons-ak.wxug.com/i/c/k/clear.gif", "title":"Tuesday Night", "fcttext":"Clear. Low of 70F. Winds from the NNW at 10 to 15 mph.", "fcttext_metric":"Clear. Low of 21C. Breezy. Winds from the NNW at 15 to 25 km/h.", "pop":"0" } , { "period":2, "icon":"partlycloudy", "icon_url":"http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", "title":"Wednesday", "fcttext":"Clear in the morning, then partly cloudy. High of 88F. Winds from the NNW at 5 to 15 mph.", "fcttext_metric":"Clear in the morning, then partly cloudy. High of 31C. Breezy. Winds from the NNW at 10 to 25 km/h.", "pop":"0" } , { "period":3, "icon":"clear", "icon_url":"http://icons-ak.wxug.com/i/c/k/clear.gif", "title":"Wednesday Night", "fcttext":"Clear in the evening, then partly cloudy. Low of 70F. Winds from the NW at 5 to 15 mph.", "fcttext_metric":"Clear in the evening, then partly cloudy. Low of 21C. Breezy. Winds from the NW at 10 to 25 km/h.", "pop":"0" } , { "period":4, "icon":"partlycloudy", "icon_url":"http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", "title":"Thursday", "fcttext":"Clear in the morning, then partly cloudy. High of 88F. Winds from the North at 5 to 10 mph shifting to the WSW in the afternoon.", "fcttext_metric":"Clear in the morning, then partly cloudy. High of 31C. Winds from the North at 5 to 15 km/h shifting to the WSW in the afternoon.", "pop":"0" } , { "period":5, "icon":"clear", "icon_url":"http://icons-ak.wxug.com/i/c/k/clear.gif", "title":"Thursday Night", "fcttext":"Clear. Low of 73F. Winds from the WNW at 5 to 10 mph.", "fcttext_metric":"Clear. Low of 23C. Winds from the WNW at 5 to 15 km/h.", "pop":"0" } , { "period":6, "icon":"clear", "icon_url":"http://icons-ak.wxug.com/i/c/k/clear.gif", "title":"Friday", "fcttext":"Clear. High of 88F. Winds from the NNE at 5 to 10 mph shifting to the WSW in the afternoon.", "fcttext_metric":"Clear. High of 31C. Winds from the NNE at 5 to 20 km/h shifting to the WSW in the afternoon.", "pop":"0" } , { "period":7, "icon":"clear", "icon_url":"http://icons-ak.wxug.com/i/c/k/clear.gif", "title":"Friday Night", "fcttext":"Clear. Low of 72F. Winds from the NW at 5 to 10 mph.", "fcttext_metric":"Clear. Low of 22C. Winds from the NW at 5 to 15 km/h.", "pop":"0" } ] }, "simpleforecast": { "forecastday": [ {"date":{ "epoch":"1360692000", "pretty":"9:00 PM AST on February 12, 2013", "day":12, "month":2, "year":2013, "yday":42, "hour":21, "min":"00", "sec":0, "isdst":"0", "monthname":"February", "weekday_short":"Tue", "weekday":"Tuesday", "ampm":"PM", "tz_short":"AST", "tz_long":"Asia/Riyadh"}, "period":1, "high": { "fahrenheit":"84", "celsius":"29" }, "low": { "fahrenheit":"70", "celsius":"21" }, "conditions":"Partly Cloudy", "icon":"partlycloudy", "icon_url":"http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", "skyicon":"mostlysunny", "pop":0, "qpf_allday": { "in": 0.00, "mm": 0.0 }, "qpf_day": { "in": 0.00, "mm": 0.0 }, "qpf_night": { "in": 0.00, "mm": 0.0 }, "snow_allday": { "in": 0, "cm": 0 }, "snow_day": { "in": 0, "cm": 0 }, "snow_night": { "in": 0, "cm": 0 }, "maxwind": { "mph": 17, "kph": 27, "dir": "NW", "degrees": 317 }, "avewind": { "mph": 14, "kph": 22, "dir": "NW", "degrees": 324 }, "avehumidity": 52, "maxhumidity": 74, "minhumidity": 43 } , {"date":{ "epoch":"1360778400", "pretty":"9:00 PM AST on February 13, 2013", "day":13, "month":2, "year":2013, "yday":43, "hour":21, "min":"00", "sec":0, "isdst":"0", "monthname":"February", "weekday_short":"Wed", "weekday":"Wednesday", "ampm":"PM", "tz_short":"AST", "tz_long":"Asia/Riyadh"}, "period":2, "high": { "fahrenheit":"88", "celsius":"31" }, "low": { "fahrenheit":"70", "celsius":"21" }, "conditions":"Partly Cloudy", "icon":"partlycloudy", "icon_url":"http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", "skyicon":"partlycloudy", "pop":0, "qpf_allday": { "in": 0.00, "mm": 0.0 }, "qpf_day": { "in": 0.00, "mm": 0.0 }, "qpf_night": { "in": 0.00, "mm": 0.0 }, "snow_allday": { "in": 0, "cm": 0 }, "snow_day": { "in": 0, "cm": 0 }, "snow_night": { "in": 0, "cm": 0 }, "maxwind": { "mph": 14, "kph": 22, "dir": "NW", "degrees": 308 }, "avewind": { "mph": 12, "kph": 19, "dir": "NW", "degrees": 315 }, "avehumidity": 51, "maxhumidity": 75, "minhumidity": 39 } , {"date":{ "epoch":"1360864800", "pretty":"9:00 PM AST on February 14, 2013", "day":14, "month":2, "year":2013, "yday":44, "hour":21, "min":"00", "sec":0, "isdst":"0", "monthname":"February", "weekday_short":"Thu", "weekday":"Thursday", "ampm":"PM", "tz_short":"AST", "tz_long":"Asia/Riyadh"}, "period":3, "high": { "fahrenheit":"88", "celsius":"31" }, "low": { "fahrenheit":"73", "celsius":"23" }, "conditions":"Partly Cloudy", "icon":"partlycloudy", "icon_url":"http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", "skyicon":"mostlysunny", "pop":0, "qpf_allday": { "in": 0.00, "mm": 0.0 }, "qpf_day": { "in": 0.00, "mm": 0.0 }, "qpf_night": { "in": 0.00, "mm": 0.0 }, "snow_allday": { "in": 0, "cm": 0 }, "snow_day": { "in": 0, "cm": 0 }, "snow_night": { "in": 0, "cm": 0 }, "maxwind": { "mph": 9, "kph": 14, "dir": "West", "degrees": 259 }, "avewind": { "mph": 7, "kph": 11, "dir": "WSW", "degrees": 250 }, "avehumidity": 51, "maxhumidity": 69, "minhumidity": 37 } , {"date":{ "epoch":"1360951200", "pretty":"9:00 PM AST on February 15, 2013", "day":15, "month":2, "year":2013, "yday":45, "hour":21, "min":"00", "sec":0, "isdst":"0", "monthname":"February", "weekday_short":"Fri", "weekday":"Friday", "ampm":"PM", "tz_short":"AST", "tz_long":"Asia/Riyadh"}, "period":4, "high": { "fahrenheit":"88", "celsius":"31" }, "low": { "fahrenheit":"72", "celsius":"22" }, "conditions":"Clear", "icon":"clear", "icon_url":"http://icons-ak.wxug.com/i/c/k/clear.gif", "skyicon":"mostlysunny", "pop":0, "qpf_allday": { "in": 0.00, "mm": 0.0 }, "qpf_day": { "in": 0.00, "mm": 0.0 }, "qpf_night": { "in": 0.00, "mm": 0.0 }, "snow_allday": { "in": 0, "cm": 0 }, "snow_day": { "in": 0, "cm": 0 }, "snow_night": { "in": 0, "cm": 0 }, "maxwind": { "mph": 10, "kph": 16, "dir": "WSW", "degrees": 248 }, "avewind": { "mph": 7, "kph": 11, "dir": "WSW", "degrees": 248 }, "avehumidity": 53, "maxhumidity": 60, "minhumidity": 38 } ] } }}null
答案 0 :(得分:3)
您似乎不明白Gson
的作用。它是一个JSON解析器,特别是将JSON反序列化为Java POJO的解析器。
在您的代码中,您有:
String wdf = g.fromJson(message, String.class);
您告诉Gson将JSON反序列化为Java String
对象。它不能那样做;你的JSON 不是一个String
对象 - 它是从Weather Underground返回的一个大JSON对象。您已经拥有包含JSON文本本身的Java String
(message
)。
您需要创建一个可以将JSON反序列化的POJO,或者使用Gson的解析器和关联的对象/方法从您想要的JSON中选择部分。
以下是POJO的开头(所有字段都是公开的,没有getter / setter只是为了让这个例子变小):
class MyWUPojo {
public Response response;
// more after this that match the JSON
}
class Response {
public String version;
public String termsofservice;
public Map<String, Integer> features;
}
然后,您将JSON反序列化为MyWUPojo
的实例,其中包含:
MyWUPojo wup = new Gson().fromJson(message,MyWUPojo.class);
如果你不想去POJO路线你可以解析JSON,然后从中得到你想要的东西:
JsonObject o = (JsonObject) new JsonParser().parse(message);
现在您可以使用JsonObject
的各种方法来访问已解析的JSON。 (见:http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/JsonObject.html)
GSON User's Guide编写得非常好,并且非常详细地解释了这一点。
编辑添加: JSON末尾的null
是由此引起的:
while(message!=null){
message = reader.readLine();
buf.append(message);
}
您追加null
然后循环退出。它必须是:
while ((message = reader.readline()) != null) {
buf.append(message);
}