【问题标题】:Gson not deserializing JSON dataGson 没有反序列化 JSON 数据
【发布时间】:2015-06-11 07:48:27
【问题描述】:

我正在尝试从 Yahoo API 获取一些天气信息。这是我的 JSON:

JSON

这是我的 DTO:

public class forecast implements Serializable {

private static final long serialVersionUID = -520652416977871134L;
private String text;
private String high;
private String day;
private String code;
private String low;
private String date;

public forecast() {
}


public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

public String getHigh() {
    return high;
}

public void setHigh(String high) {
    this.high = high;
}

public String getDay() {
    return day;
}

public void setDay(String day) {
    this.day = day;
}

public String getCode() {
    return code;
}

public void setCode(String code) {
    this.code = code;
}

public String getLow() {
    return low;
}

public void setLow(String low) {
    this.low = low;
}

public String getDate() {
    return date;
}

public void setDate(String date) {
    this.date = date;
}

@Override
public String toString() {
    return "ClassPojo [text = " + text + ", high = " + high + ", day = "
            + day + ", code = " + code + ", low = " + low + ", date = "
            + date + "]";
}
}

我只对forecast 元素感兴趣。

当我尝试读取反序列化到我的 DTO 中的数据时,所有这些数据都是空的。我感觉我没有正确格式化我的 DTO。

另外,将 JSON 映射到 POJO 的正确方法是什么?

编辑:这是我的反序列化代码

    String endpoint = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20"
            + "where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Rhodes%2C%20Gr%22)&"
            + "format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
    try {
        URL endpointURL = new URL(endpoint);
        HttpURLConnection connection = (HttpURLConnection) endpointURL
                .openConnection();
        connection.connect();
        InputStream input = connection.getInputStream();
        JsonReader reader = new JsonReader(new InputStreamReader(input));
        reader.setLenient(true);
        forecast response = new Gson().fromJson(reader,
                forecast.class);
        Log.d("forecast", response.toString());//override toString() to return all the values of the object
    } catch (IOException e) {
        e.printStackTrace();
    }

【问题讨论】:

  • 您使用 GSON 的代码在哪里?
  • 添加了我使用 GSON 的代码
  • 你是如何调用Gson的?由于forecast 是内部元素之一,并且它是一组对象,因此您不能忽略其他所有内容并直接从 JSON 中获取一个 forecast 实例。
  • 那我应该如何创建我的 DTO?

标签: java json serialization gson


【解决方案1】:

您的 JSON(您从 Yahoo 获得)非常复杂。所以它不能轻易地映射到简单的 POJO(但你仍然可以编写包含所有相应嵌套 JSON 元素的字段的巨大 POJO)。

但可以从 JSON 中解析和提取特定元素。

代码:

public static void main(String[] args) {
    String endpoint = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20"
            + "where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Rhodes%2C%20Gr%22)&"
            + "format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
    try {
        URL endpointURL = new URL(endpoint);
        HttpURLConnection connection = (HttpURLConnection) endpointURL
                .openConnection();
        connection.connect();
        InputStream input = connection.getInputStream();
        JsonReader reader = new JsonReader(new InputStreamReader(input));
        reader.setLenient(true);

        JsonElement forecastSubObject = new JsonParser().parse(reader).
                getAsJsonObject().get("query").
                getAsJsonObject().get("results").
                getAsJsonObject().get("channel").
                getAsJsonObject().get("item").
                getAsJsonObject().get("forecast");  

        System.out.println(forecastSubObject.toString());   

        List<forecast> forecasts = (List<forecast>)new Gson().fromJson(forecastSubObject, List.class);

        System.out.println("forecast : " + forecasts);
        System.out.println("first forecast: " + forecasts.get(0));      
    } catch (IOException e) {
        e.printStackTrace();
    }
}

使用JsonParser,您可以遍历元素(按他们的名字)。当达到“预测”元素时,提取相应的字符串。然后它像往常一样解析对象并映射到您的预测 POJO 列表。

一般来说,与 JSON 的映射关系非常广泛。不同的库提供了不同的方法来实现这一点(从简单而肮脏到复杂但可靠)。

【讨论】:

  • 感谢您的回答@flaz14。让我试试这个然后回复你。
  • 好吧,我只需要预测元素所以我尝试将getAsJsonObject().get("forecast") but still the object is null. Any idea on this? I've also noticed that the forecast` 是一个数组,但是 GSON api 不同意我抛出一个异常说这不是一个数组。
  • 我已经编辑了代码。所以整个预测 POJO 数组被加载 List&lt;forecast&gt; forecasts = (List&lt;forecast&gt;)new Gson().fromJson(forecastSubObject, List.class); 加载这个数组。然后可以从forecasts 列表中获取任何想要的项目。
  • Gson 库的逻辑是这样的:从 JSON 的根中取出名为“query”的元素,然后从“query”中取出名为“results”的元素,以此类推,直到我们到达元素命名为“项目”(某种嵌套搜索,您应该定义所需元素的完整路径)。 “预测”项目嵌套在“项目”中。所以我们偷看前者。如果getAsJsonObject().get("forecast")从JSON的根加载“预测”元素,找不到它然后返回null。
猜你喜欢
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
相关资源
最近更新 更多