如何在SpringBoot中使用Jackson将JSON对象数组解析为DTO

时间:2017-11-13 11:26:14

标签: java arrays json spring jackson

我目前正在构建一个使用RestTemplate构建对Alpha Vantage API的API请求的应用程序。以下是排除不必要元数据的示例响应:

{
  "Time Series (Daily)": {
    "2017-11-10": {
      "1. open": "83.7900",
      "2. high": "84.1000",
      "3. low": "83.2300",
      "4. close": "83.8700",
      "5. volume": "19340435"
    },
    "2017-11-09": {
      "1. open": "84.1100",
      "2. high": "84.2700",
      "3. low": "82.9000",
      "4. close": "84.0900",
      "5. volume": "20924172"
    },
    "2017-11-08": {
      "1. open": "84.1400",
      "2. high": "84.6100",
      "3. low": "83.8300",
      "4. close": "84.5600",
      "5. volume": "18034170"
    },
    "2017-11-07": {
      "1. open": "84.7700",
      "2. high": "84.9000",
      "3. low": "83.9300",
      "4. close": "84.2700",
      "5. volume": "17152583"
    },
    "2017-11-06": {
      "1. open": "84.2000",
      "2. high": "84.7000",
      "3. low": "84.0800",
      "4. close": "84.4700",
      "5. volume": "19039847"
    },
    "2017-11-03": {
      "1. open": "84.0800",
      "2. high": "84.5400",
      "3. low": "83.4000",
      "4. close": "84.1400",
      "5. volume": "17569120"
    }
  }
}

我正在构建我的数据传输对象层,它包含在内:

顶层:

public class Stock extends Dto{

    @JsonProperty("Time Series (Daily)")
    private TimeSeries timeSeries;

    public TimeSeries getTimeSeries() {
        return timeSeries;
    }

    public void setTimeSeries(TimeSeries timeSeries) {
        this.timeSeries = timeSeries;
    }
}

中间层:

public class TimeSeries extends Dto{

    private List<Day> days;

    public List<Day> getDays() {
        return days;
    }

    public void setDays(List<Day> days) {
        this.days = days;
    }
}

最终层(数据平移):

@JsonIgnoreProperties(ignoreUnknown = true)
public class Day extends Dto{

    @JsonProperty("1. open")
    private double open;

    @JsonProperty("2. high")
    private double high;

    @JsonProperty("3. low")
    private double low;

    @JsonProperty("4. close")
    private double close;

    @JsonProperty("5. volume")
    private double volume;

    public double getOpen() {
        return open;
    }

    public void setOpen(double open) {
        this.open = open;
    }

    public double getHigh() {
        return high;
    }

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

    public double getLow() {
        return low;
    }

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

    public double getClose() {
        return close;
    }

    public void setClose(double close) {
        this.close = close;
    }

    public double getVolume() {
        return volume;
    }

    public void setVolume(double volume) {
        this.volume = volume;
    }
}

运行我的应用程序时会发生什么: 当我运行应用程序时,顶层(Stock.java)会填充一个Time Series对象,但是下一层(TimeSeries.java)不包含我期望的(Day.java)对象数组,它是null。我试过了:

@JSONProperty("2017-11-10") 
private Day day;

这确实有效,并弥补了中间层与最后一层之间的差距,数据很好......但这不是我所追求的。

我希望发生/想要发生的事情: 我想在日期列表中获取所有日期(在TimeSeries.java中)的数组,但它不会工作,我相信这是因为JSON响应不能将它们作为数组提供JavaScript对象,而不是实际的键和对,所以我不能只列出它们,但必须直接深入到最终对象......这不是我想要的。

我已阅读过有关此主题的主题

Parse JSON array with resttemplate

Parsing JSON with Jackson

Parsing JSON with Jackson Java

Unable to consume JSON array using Spring RestTemplate

How to use query parameter represented as JSON with Spring RestTemplate?

How to deserialize an array of objects using Jackson or any other api?

desrialize JSON with child array using Jackson annotations?

Jackson Mapping List of String or simple String

Where should I get the object to represent what is passed (Json) in a RESTful api

如果有人知道如何让中间步骤工作并将对象实际存储在密钥&#34;时间序列(每日)&#34;然后,几天就可以访问他们非常棒的价值。

注意:此外,如果您要对此进行投票,请在下面说明您为什么这样做。我在过去的5个小时里对此进行了研究,所以我相信我已经做了尽职调查,可以在这里问我,并且我已经尽可能彻底了...... c&#39; mon。

1 个答案:

答案 0 :(得分:3)

你的json中没有Json数组。实际上你有json对象有多个字段,所以你的java数据结构应该用Map表示而不是List。如果你想保持当前的类结构,那么你应该明白,你丢失了时间序列的日期部分。我不认为你想要这个。

选项1.使用HashMap<String, Day> timeSeries

public class Stock {

    @JsonProperty("Time Series (Daily)")
    private HashMap<String, Day> timeSeries;

    public HashMap<String, Day> getTimeSeries() {
        return timeSeries;
    }

    public void setTimeSeries(HashMap<String, Day> timeSeries) {
        this.timeSeries = timeSeries;
    }
}

选项2.更改TimeSeries代码

public class TimeSeries {

    // TreeMap because it preserves sorting order
    @JsonIgnore
    private Map<String, Day> days = new TreeMap<>();

    @JsonAnySetter
    public void setDays(String time, Day value){
        days.put(time,value);
    }

    @JsonAnyGetter
    public Map<String, Day> getData() {
        return days;
    }

    // add getDays() if you need only values
    // and if you need list, can use new ArrayList(days.values()) 
    @JsonIgnore
    public Collection<Day> getDays(){
        return days.values();
    }
}