gpt4 book ai didi

java - 使用 Jackson 的 JSON 数据特殊字段

转载 作者:行者123 更新时间:2023-11-30 03:36:58 25 4
gpt4 key购买 nike

我有一个具有特殊属性的数据结构。该数据结构代表全天的股票定价数据。 [所以基本上是 OLHC] 在我当前的序列化例程和构建器中,我当前支持“全部”属性。这是构建器中的一种方法,可将所有 OHLC 价格设置为一个价格。

有没有一种方法可以在不需要拥有所有属性名称的情况下进行设置?

  • 在序列化时,它应该进行比较并使用所有
  • 反序列化时,它应该重定向到构建器中的 all 方法。

这在 jackson 可能吗?

示例:

数据结构如下:

EODPrice 

- Open
- Low
- Close
- High

假设我们有 json: "{all: 5.00}"它将反序列化为开盘价:5.00、最低价:5.00、收盘价:5.00 和最高价:5.00。如果我们要序列化,我想改变行为,这样如果我们有 Open == Low == Close == High 那么我们将创建一个名为 all 的属性。如果该条件不成立,那么我们根本不会序列化“all”属性。

最佳答案

通过使用注释@JsonFilter,序列化部分绝对是可能的,您可以在 Jackson documentation 中阅读该注释。 .

反序列化是使用 @JsonCreator 的标准 Jackson。

过滤器可以应用于类、方法和字段,您可以编写自己的自定义过滤器来处理打开、低、关闭、高问题。

检查this tutorial精彩的介绍。

有关代码示例,请查看此。首先,使用 @JsonFilter 注释声明您的 EODPrice

@JsonIgnoreProperties(ignoreUnknown = true) // required to skip the "all" attribute in the JSON
@JsonFilter("allFilter") // Specify the filter
public class EODPrice {
private final BigDecimal close;
private final BigDecimal high;
private final BigDecimal low;
private final BigDecimal open;

// Builder method, does not include "all"
@JsonCreator
public EODPrice(
@JsonProperty("open") final BigDecimal open,
@JsonProperty("low") final BigDecimal low,
@JsonProperty("close") final BigDecimal close,
@JsonProperty("high") final BigDecimal high) {

this.open = open;
this.low = low;
this.close = close;
this.high = high;
}

// This is not part of the JSON but puts the business logic in the POJO
@JsonIgnore
public boolean allFieldsEqual() {
return open.equals(low) && open.equals(close) && open.equals(high);
}

public BigDecimal getAll() {
if (allFieldsEqual()) {
return open;
}
return BigDecimal.ZERO;
}

public BigDecimal getClose() {
return close;
}

public BigDecimal getHigh() {
return high;
}

public BigDecimal getLow() {
return low;
}

public BigDecimal getOpen() {
return open;
}
}

过滤器可能看起来像这样:

private PropertyFilter allFilter = new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField(
Object pojo,
JsonGenerator jgen,
SerializerProvider provider,
PropertyWriter writer) throws Exception {

// If it is not the "all" property, go on with normal serialization
if (!writer.getName().equals("all")) {
writer.serializeAsField(pojo, jgen, provider);
return;
}

// Else, check the special all-rule
final EODPrice eodPrice = (EODPrice) pojo;
if (eodPrice.allFieldsEqual()) {
// Only serialize if all fields are equal
writer.serializeAsField(pojo, jgen, provider);
}
}

@Override
protected boolean include(BeanPropertyWriter writer) {
return true;
}

@Override
protected boolean include(PropertyWriter writer) {
return true;
}
};

最后,设置映射器。此测试用例说明了过滤器的启动:

@Test
public void testJsonRoundtrip() throws IOException {
final FilterProvider filters = new SimpleFilterProvider().addFilter("allFilter", allFilter);
final EODPrice eodPriceWithAll = new EODPrice(BigDecimal.ONE, BigDecimal.ONE, BigDecimal.ONE, BigDecimal.ONE);
final EODPrice eodPriceWithoutAll = new EODPrice(BigDecimal.TEN, BigDecimal.ONE, BigDecimal.ONE, BigDecimal.ONE);

final ObjectMapper mapper = new ObjectMapper();
mapper.setFilters(filters);

// First, test serialization
final String eodWithAllAsStr = mapper.writeValueAsString(eodPriceWithAll);
final String eodWithoutAllAsStr = mapper.writeValueAsString(eodPriceWithoutAll);

Assert.assertTrue(eodWithAllAsStr.contains("all"));
Assert.assertFalse(eodWithoutAllAsStr.contains("all"));

// Then, test deserialization
final EODPrice eodPriceWithAll2 = mapper.readValue(eodWithAllAsStr, EODPrice.class);
final EODPrice eodPriceWithoutAll2 = mapper.readValue(eodWithoutAllAsStr, EODPrice.class);

Assert.assertTrue(eodPriceWithAll2.allFieldsEqual());
Assert.assertFalse(eodPriceWithoutAll2.allFieldsEqual());
}

编辑: OP 更新后反序列化被添加到 POJO 中。此外,业务逻辑从过滤器移至 POJO。

关于java - 使用 Jackson 的 JSON 数据特殊字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27652276/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com