如何通过注释有条件地使用自定义 JsonSerializer



我编写了一个自定义的JsonSerializer来将BigDecimal 转换为String。我想使用@JsonSerialize注释调用这个序列化程序,但有条件地,即如果特定的布尔值只为真,那么这个 BigDecimal 到字符串的转换应该完成,否则就不行了。

我有一个POJO,它有一个大十进制价格字段。发送此 POJO 是为了响应两个休息呼叫:

  • 期望价格字段为数字值//所以@JsonSerialize应该 不运行
  • 期望价格字段为字符串值//so @JsonSerialize 应该运行

谁能建议我如何实现它?

下面是我编写的自定义序列化程序的代码片段:

public class BigDecimalToStringSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException,
JsonProcessingException {
gen.writeString(value.toString());
}
}

具有价格字段的POJO文件:

JsonInclude(Include.NON_NULL)
public class Price{
private BigDecimal price;
public Price() {
}
@JsonSerialize(using = BigDecimalToStringSerializer.class)
public BigDecimal getPrice() {
return price;
}   
public void setPrice(BigDecimal pric) {
this.price  = price;
}
}

提前感谢一吨!!

您可以为此实现一个PropertyFilter。首先,您需要使用@JsonFilter注释在我们的实体上定义过滤器:

@JsonFilter("stringValueFilter")
public class Price {
private BigDecimal price;
public Price() {
}
public BigDecimal getPrice() {
return price;
}   
public void setPrice(BigDecimal pric) {
this.price  = price;
}
}

这是你的PropertyFilter

public interface PropertyFilter {
void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider prov, PropertyWriter writer);
void serializeAsElement(Object elementValue, JsonGenerator jgen, SerializerProvider prov, PropertyWriter writer) throws Exception;
void depositSchemaProperty(PropertyWriter writer, JsonObjectFormatVisitor objectVisitor, SerializerProvider provider) throws JsonMappingException;
@Deprecated 
void depositSchemaProperty(PropertyWriter writer, ObjectNode propertiesNode, SerializerProvider provider) throws JsonMappingException;
}

第一种方法需要针对您的情况进行特殊实现:

public class StringValueFilter implements PropertyFilter {
void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider prov, PropertyWriter writer) {
if (pojo instanceof Price && isValueFieldNumber((Price) pojo)) {
return; // skip this field
}
writer.serializeAsField(pojo, jgen, prov);
}
private isValueFieldNumber(Price price) {
return: //check your logic and return
}
void serializeAsElement(Object elementValue, JsonGenerator jgen, SerializerProvider prov, PropertyWriter writer) throws Exception {
writer.serializeAsField(elementValue, jgen, prov);
}
void depositSchemaProperty(PropertyWriter writer, JsonObjectFormatVisitor objectVisitor, SerializerProvider provider) throws JsonMappingException {
writer.depositSchemaProperty(objectVisitor);
}
@Deprecated 
void depositSchemaProperty(PropertyWriter writer, ObjectNode propertiesNode, SerializerProvider provider) throws JsonMappingException {
writer.depositSchemaProperty(propertiesNode, provider);
}
}

此筛选器包含根据price字段的值决定是否序列化的实际逻辑。

接下来,您需要将此过滤器挂接到ObjectMapper

final ObjectMapper mapper = new ObjectMapper();
final FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("stringValueFilter", new StringValueFilter());
mapper.setFilters(filterProvider);

1.把@JsonFilter放在你身上 价格等级:

@JsonFilter("myFilter")
@JsonInclude(Include.NON_NULL)
public class Price {
private BigDecimal price;
public Price() {}
@JsonSerialize(using = BigDecimalToStringSerializer.class)
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal pric) {
this.price = price;
}
}

2.定义自定义过滤器逻辑

检查字段是否为"price":
如果不是,则正常序列化并返回
如果是,请检查您的布尔字段以查看您是否进行了序列化

public class CustomFilter extends SimpleBeanPropertyFilter {
@Override
public void serializeAsField
(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer)
throws Exception {
if (include(writer)) {
if (!writer.getName().equals("price")) {
writer.serializeAsField(pojo, jgen, provider);
return;
}
Boolean toSerializeOrNot = ((MyDtoWithFilter) pojo).getYourCoditionalField();
if (toSerializeOrNot) {
writer.serializeAsField(pojo, jgen, provider);
}
} else if (!jgen.canOmitFields()) { 
writer.serializeAsOmittedField(pojo, jgen, provider);
}
}
@Override
protected boolean include(BeanPropertyWriter writer) {
return true;
}
@Override
protected boolean include(PropertyWriter writer) {
return true;
}
}

更多信息

https://www.baeldung.com/jackson-serialize-field-custom-criteria

自定义序列化程序类中唯一需要更改:

public class BigDecimalToStringSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException,
JsonProcessingException {
if (pojo instanceof Price && ((Price) pojo).shouldConvertInString()) {
gen.writeString(value.toString());
} else {
gen.writeNumber(value);
}
}

}

最新更新