簡體   English   中英

Jackson 注釋 - 通過將索引映射到屬性將數組解組為 object

[英]Jackson annotations - Unmarshall array as object by mapping index to property

我正在閱讀 stream,它提供了用於計算市場深度的訂單簿的更新。 每個都包含訂單簿的新條目列表。 每個條目包含三個屬性。

  1. 市場方面(例如買入或賣出)
  2. 商品成交數量
  3. 本次交易商品單價

這些條目在 JSON 中表示為數組節點。 以下是如何提供條目的示例。

{
    "Changes": [
        { "entry": ["buy","470.84724800000004","16.14963"] },
        { "entry": ["buy","470.787392","0.01"] },
        { "entry": ["sell","473.112752","9.325423"] },
        { "entry": ["sell","473.052608","11.80723"] }
    ],
    ...some more fields; not relevant to this question...
}

如您所見,每個條目數組的索引用作字段名稱。 每個數組元素的 position 定義了它代表什么屬性。 邊在索引 0,單價在索引 1,數量在索引 2。

我如何使用 Java 8 中的 arrays Jackson 注釋反序列化它們? 我只問最里面的 arrays。一般來說,我不需要 object 結構的幫助。

我嘗試制作類似於以下內容的 class。

public class OrderBookEntry {
    final String side;
    final BigDecimal price;
    final BigDecimal quantity;

    @JsonCreator
    public OrderBookEntry(@JsonProperty(index = 0, required = true) String side,
                          @JsonProperty(index = 1, required = true) BigDecimal price,
                          @JsonProperty(index = 2, required = true) BigDecimal quantity) {
        this.side = side;
        this.price = price;
        this.quantity = quantity;
    }
}

我嘗試在 class 上指定@JsonFormat.Shape.ARRAY 。每次我嘗試反序列化示例字符串時,我都會得到一個InvalidDefinitionException

線程“main”中的異常 com.fasterxml.jackson.databind.exc.InvalidDefinitionException:

類型 com.example.OrderBookEntry 的類型定義無效:參數 #0 沒有屬性名稱,不可注入:不能用作 Creator [com.example.OrderBookEntry 的構造函數,注釋:{接口 com.fasterxml.jackson.JsonCrenotation. =@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] [來源:(String)]["buy","470.84724800000004","16.14963"]"; 行:1,列:1]

有沒有辦法只用注釋來做到這一點?


PS(咆哮)

我只想補充一點,這是一個荒謬的數據結構。 這沒有道理。 使用數組索引而不是 object 字段名稱的目的是減少消息的大小。 這是財務數據 stream,任何對財務數據網絡延遲的改進都是可取的。 但是,圍繞這些 arrays 的每一個都是一個完全多余的包裝器 object,它只有一個命名字段。 這會為每個條目增加至少 10 字節的不必要流量。 數據結構的設計非常糟糕。

有不止一種方法可以做到這一點,但我總是更喜歡將專用 class 與專用序列化器結合使用。 其他選擇是:

  • 使用 ObjectMapper 注冊序列化程序——顯式編碼而不是(元級別)注釋
  • 使用通用設置方法(使用 Map<String, Object>)——在冗長的方法中隱藏序列化程序的方面
  • 將 JsonNode 與父 class 中的 setter 映射——如#2

反而:

@JsonDeserialize(using = OrderBookEntryDeserializer.class)
public class OrderBookEntry {
  // no further Jackson-annotations necessary
}

和序列化器:

class OrderBookEntryDeserializer extends StdDeserializer<OrderBookEntry> {
    OrderBookEntryDeserializer() {
        super(OrderBookEntry.class);
    }

    @Override
    public OrderBookEntry deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        final JsonNode node = p.getCodec().readTree(p);
        // now follow Jackson API to turn the node into
        // an ArrayNode, there are plenty of is-methods
        // and it requires a hard cast.
    }

我的示例使用 package 私有反序列化器 class,它工作得很好,並將其鎖定在其 package(最好在 OrderBookEntry 旁邊)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM