【问题标题】:How to deserialize JSON data from an IEX Cloud batch endpoint如何从 IEX 云批处理端点反序列化 JSON 数据
【发布时间】:2021-06-22 22:54:15
【问题描述】:

我正在从 IEX 云批处理端点请求数据。该请求包含一个带有多个交易品种的查询字符串并返回相关的市场数据。为了使问题更简单,我只显示下面响应的一个子集。我还使用https://www.jsonschema2pojo.org/ 自动构建我的 POJO 并将其显示在请求下方。我的请求在示例中包含一批用于 AAPL 和 FB 的符号,但它可以包含任意数量的用户在生产中选择的符号。鉴于响应的结构,如何创建通用符号 POJO?正如您在下面看到的,JSONSchema 为每个符号创建一个 POJO(例如 Aapl POJO 和 FB POJO),但我并不总是知道请求了什么符号或其中有多少。

来自批量符号请求的 IEX 云响应。

{
    "AAPL": {
        "quote": {
            "symbol": "AAPL",
            "latestPrice": 133.985
        }
    },
    "FB": {
        "quote": {
            "symbol": "FB",
            "latestPrice": 339.13
        }
    }
}

由 JSONSchema.org 构建的 POJO。

-----------------------------------com.example.Aapl.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"quote"
})
@Generated("jsonschema2pojo")
public class Aapl {

@JsonProperty("quote")
public Quote quote;

}
-----------------------------------com.example.Fb.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"quote"
})
@Generated("jsonschema2pojo")
public class Fb {

@JsonProperty("quote")
public Quote__1 quote;

}
-----------------------------------com.example.Quote.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"symbol",
"latestPrice"
})
@Generated("jsonschema2pojo")
public class Quote {

@JsonProperty("symbol")
public String symbol;
@JsonProperty("latestPrice")
public Double latestPrice;

}
-----------------------------------com.example.Quote__1.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"symbol",
"latestPrice"
})
@Generated("jsonschema2pojo")
public class Quote__1 {

@JsonProperty("symbol")
public String symbol;
@JsonProperty("latestPrice")
public Double latestPrice;

}
-----------------------------------com.example.Security.java-----------------------------------

package com.example;

import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"AAPL",
"FB"
})
@Generated("jsonschema2pojo")
public class Security {

@JsonProperty("AAPL")
public Aapl aapl;
@JsonProperty("FB")
public Fb fb;

}

【问题讨论】:

  • 你可能想要@JsonRootName("quote")Map<String, Quote>

标签: java json jackson


【解决方案1】:

"AAPL""FB"dynamic 字段名称,因此您不能使用类的 fixed-name 字段来映射它们,而是应该使用根对象中的 Map<String, ...> 字段。

"AAPL""FB" 的值是相同的结构,即具有名为 quote 的字段的对象,因此您需要一个与之匹配的类。

quote 的值是一个具有两个字段的对象,分别名为 symbollatestPrice,因此您需要一个与之匹配的类。

class Root {
    private Map<String, Stock> stocks = new LinkedHashMap<>();

    @JsonAnyGetter
    public Map<String, Stock> getStocks() {
        return this.stocks;
    }

    @JsonAnySetter
    public void addStock(String name, Stock value) {
        this.stocks.put(name, value);
    }
}
class Stock {
    private Quote quote;

    public Quote getQuote() {
        return this.quote;
    }

    public void setQuote(Quote quote) {
        this.quote = quote;
    }
}
class Quote {
    private String symbol;
    private BigDecimal latestPrice;

    public String getSymbol() {
        return this.symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public BigDecimal getLatestPrice() {
        return this.latestPrice;
    }

    public void setLatestPrice(BigDecimal latestPrice) {
        this.latestPrice = latestPrice;
    }
}

【讨论】:

  • 我使用了你提到的结构;但是,在调试我的代码时,我注意到 stocks 在处理响应后是一个空的哈希图。我已确认我的请求针对的是正确的端点。任何想法我做错了什么?感谢您的精彩回复。
  • @Michael 您需要使用@JsonAnyGetter@JsonAnySetter 进行注释。注意“setter”实际上是一个“add”方法,而不是“set”方法。
  • Root 类不是必需的;直接使用Map&lt;String, Quote&gt;即可。
猜你喜欢
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 2023-03-15
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多