使用注释@JsonFilter 绝对可以实现序列化部分,您可以在Jackson documentation 中阅读该注释。
反序列化是标准的杰克逊使用@JsonCreator。
过滤器可以应用于类、方法和字段,您可以编写自己的自定义过滤器来处理打开、低、关闭、高问题。
查看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。