【问题标题】:Denormalizing nested JSON object hierarchies in Jackson在 Jackson 中对嵌套的 JSON 对象层次结构进行非规范化
【发布时间】:2013-11-27 04:24:43
【问题描述】:

假设我有一个 JSON 对象层次结构,如下所示:

{
    "name": "Mosquito Laser",

    "configurations": [{
        "currency": "USD",
        "price": "10.00" /* the Basic option */
    }, {
        "currency": "USD",
        "price": "50.00" /* the Pro option */
    }, ]

}

我想将此 json 反序列化为 java 对象,并将其展平为单个级别。所以举个例子,我想把上面的json映射成下面的java类:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Product {

    @JsonProperty
    protected String name;

    protected String lowestPrice;
    protected String highestPrice;

}

我想使用自定义方法从 json 中的配置列表中计算 lowestPricehighestPrice 字段。假设为了清楚起见,这里已经简化了 json 层次结构和 java 对象,而实际上它们实际上要复杂得多,因此我不希望实现完全自定义的反序列化器。我希望使用 Jackson 的数据绑定默认值自动反序列化大多数字段,但我想为某些字段指定自定义操作。

有没有一种简单的方法可以告诉 Jackson 使用特殊方法自动计算 lowestPricehighestPrice 字段的值?

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    用途:

    @JsonProperty("configuration")
    @JsonDeserialize(using = ConfigurationDeserializer.class)
    protected String cheapestPrice;
    

    反序列化器看起来像这样:

    public class ConfigurationDeserializer extends JsonDeserializer<String> {
    
        @Override
        public String deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
            (your logic to go from the configuration JSON to cheapestPrice goes here)
        }
    } 
    

    【讨论】:

    • 好的,这是一个很好的解决方案,但是我意识到我有一个额外的约束,我没有意识到它很重要。我实际上需要计算多个计算字段,而不仅仅是一个。我不确定如何使用此解决方案来做到这一点,因为计算第一个字段会吞噬流解析器中的令牌。我会更新问题
    • @emmby 我认为唯一的解决方案是为这两个字段设置一个特定的类。或者在你的父类上使用 Deserializer。
    【解决方案2】:

    在 ETL 和 SQL 中,这是聚合。几个问题:

    • 您需要汇总这些值吗?
    • 您需要来自较低级别 JSON 的其他值吗?
    • 内存有问题吗?
    • CPU 有问题吗?

    评论:

    • 解析树状结构时聚合需要保存状态
    • 快速流解析器不保存状态
    • 状态可以传递给子级,也可以从子级返回。
    • Jackson 在解析不需要的子值时可能会很慢。

    【讨论】:

    • 虽然此答案可能会为解决 OP 的问题提供一些见解,但建议包含一些代码示例来演示答案中概述的概念。
    【解决方案3】:

    如果您只需要修改值,只需定义 getter 方法:

    public class Product {
      public String name;
    
      protected String lowestPrice;
      protected String highestPrice;
    
      public int getLowestPrices() {
        return calculateLowest(lowestPrice);
      }
      // and similarly for highestPrice...
    }
    

    或者,在读取 JSON 时,定义匹配的 setter。方法优先于字段。

    【讨论】:

      猜你喜欢
      • 2018-03-29
      • 2017-02-23
      • 2020-05-06
      • 2017-05-02
      • 2017-09-06
      • 2016-06-20
      • 2022-01-08
      • 2019-09-04
      • 2019-10-11
      相关资源
      最近更新 更多