在Jackson中对嵌套的JSON对象层次结构进行非规范化

时间:2013-11-27 04:24:44

标签: java json jackson

假设我有一个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的数据绑定默认值自动反序列化大多数字段,但我想为某些字段指定自定义操作。

是否有一种简单的方法可以告诉杰克逊使用特殊方法自动计算lowestPricehighestPrice字段的值?

3 个答案:

答案 0 :(得分:2)

使用:

@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)
    }
} 

答案 1 :(得分:2)

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

  • 您是否需要聚合值?
  • 您是否需要来自较低级别JSON的其他值?
  • 记忆是一个问题吗?
  • CPU是一个问题吗?

评论:

  • 聚合需要在解析树状结构时保存状态
  • 快速流解析器不保存状态
  • 州可以传给孩子,也可以从孩子那里归还。
  • 解析不需要的子值时,杰克逊可能会很慢。

答案 2 :(得分:1)

如果只需修改值,只需定义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。方法优先于字段。