试图用Java解析JSON(使用Gson),得到MalformedJsonException

时间:2016-06-26 13:04:42

标签: java json parsing gson

我正在尝试从WeatherUnderground API获取天气预报数据。

到目前为止,我使用以下代码:

URLConnection connection = url.openConnection();
connection.setConnectTimeout(5000);
connection.connect();

JsonParser jp = new JsonParser();

JsonElement forecastJson = jp.parse(new InputStreamReader((InputStream) connection.getContent())).getAsJsonObject()
        .getAsJsonObject().get("forecast")
        .getAsJsonObject().get("simpleforecast")
        .getAsJsonObject().getAsJsonArray("forecastday").get(1);

System.out.println("forecastJson = " + forecastJson.toString());

String date = String.valueOf(jp.parse(forecastJson
        .getAsJsonObject().get("date")
        .getAsJsonObject().get("epoch").getAsString()));

String high = String.valueOf(jp.parse(forecastJson
        .getAsJsonObject().get("high")
        .getAsJsonObject().get("celsius").getAsString()));

String low = String.valueOf(jp.parse(forecastJson
        .getAsJsonObject().get("low")
        .getAsJsonObject().get("celsius").getAsString()));

String conditions;
try {
    conditions = String.valueOf(jp.parse(forecastJson
            .getAsJsonObject().get("conditions").getAsString()));
} catch (JsonSyntaxException e) {
    e.printStackTrace();
}

JsonElement forecastJson“我收到的内容如下:

{
  "date": {
    "epoch": "1467046800",
    "pretty": "7:00 PM CEST on June 27, 2016",
    "day": 27,
    "month": 6,
    "year": 2016,
    "yday": 178,
    "hour": 19,
    "min": "00",
    "sec": 0,
    "isdst": "1",
    "monthname": "June",
    "monthname_short": "Jun",
    "weekday_short": "Mon",
    "weekday": "Monday",
    "ampm": "PM",
    "tz_short": "CEST",
    "tz_long": "Europe/Berlin"
  },
  "period": 2,
  "high": {
    "fahrenheit": "77",
    "celsius": "25"
  },
  "low": {
    "fahrenheit": "58",
    "celsius": "14"
  },
  "conditions": "Partly Cloudy",
  "icon": "partlycloudy",
  "icon_url": "http://icons.wxug.com/i/c/k/partlycloudy.gif",
  "skyicon": "",
  "pop": 0,
  "qpf_allday": {
    "in": 0,
    "mm": 0
  },
  "qpf_day": {
    "in": 0,
    "mm": 0
  },
  "qpf_night": {
    "in": 0,
    "mm": 0
  },
  "snow_allday": {
    "in": 0,
    "cm": 0
  },
  "snow_day": {
    "in": 0,
    "cm": 0
  },
  "snow_night": {
    "in": 0,
    "cm": 0
  },
  "maxwind": {
    "mph": 15,
    "kph": 24,
    "dir": "W",
    "degrees": 260
  },
  "avewind": {
    "mph": 11,
    "kph": 18,
    "dir": "W",
    "degrees": 260
  },
  "avehumidity": 48,
  "maxhumidity": 0,
  "minhumidity": 0
}

我能够获得“日期”,“高”和“低”字符串,但我无法得到“条件”,我不明白我做错了什么。

我收到以下异常:

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON

据我所知,JSON没有格式错误。我怎么能得到“条件”值?

我也尝试过其他JSON解析器/库,但没有成功。我想继续与Gson-Library合作,我想我很接近,但卡住了。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

如果你打破了引发异常的界限,你会发现你实际上是在尝试将一个字符串解析为实际上不是 JSON的字符串。

try {
    JsonObject jo = forecastJson.getAsJsonObject();
    JsonElement je = jo.get("conditions");
    String s1 = je.getAsString();

    // at this point s1 contains the value "Partly Cloudy" which you 
    // are trying to parse as JSON.
    JsonElement je2  = jp.parse(s1);


    conditions = String.valueOf(je2);
} catch (JsonSyntaxException e) {
    e.printStackTrace();
}

答案 1 :(得分:0)

As" JB Nizet"在我的问题评论中指出,当我想要获得另一部分内容时,我每次都试图再次解析JSON。这是我(初学者)的错误。

现在我只解析一次然后直接获取内容,没有任何问题:

JsonParser jp = new JsonParser();

JsonElement forecastJson = jp.parse(new InputStreamReader((InputStream) connection.getContent())).getAsJsonObject()
        .getAsJsonObject().get("forecast")
        .getAsJsonObject().get("simpleforecast")
        .getAsJsonObject().getAsJsonArray("forecastday").get(1);

String date = forecastJson.getAsJsonObject().get("date")
        .getAsJsonObject().get("epoch").getAsString();

String high = forecastJson.getAsJsonObject().get("high")
        .getAsJsonObject().get("celsius").getAsString();

String low = forecastJson.getAsJsonObject().get("low")
        .getAsJsonObject().get("celsius").getAsString();

String conditions = forecastJson.getAsJsonObject()
        .get("conditions").getAsString();

答案 2 :(得分:-1)

首先,正如他们在评论中所说的那样,真的没有必要再解析每一篇文章。

String date = String.valueOf(jp.parse(forecastJson .getAsJsonObject().get("date") .getAsJsonObject().get("epoch").getAsString())); 是相同的: String date = forecastJson.getAsJsonObject().get("date") .getAsJsonObject().get("epoch").getAsString();

您遇到的问题实际上是我怀疑是Gson库中的错误。当它试图解析一个带有空格的字符串时,它会对该字符串进行标记,并期望在第一个单词(在这种情况下为部分)之后文档应该结束并且json格式错误,因为它没有没达到文件的末尾。

所以要解决这个问题,或者按照评论说的那样做,这在你的案例中是合理的。或者,如果你不想总是将部分多云更改为 Partly_cloudy ,它将起作用:)