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

标签 java json spring jackson

我编写了一个自定义的 JsonSerializer 来将 BigDecimal 转换为 String。我想使用 @JsonSerialize 注释调用此序列化程序,但有条件地,即如果特定 boolean 值仅为真,则应执行此 BigDecimal 到 String 的转换,否则不执行。

我有一个 POJO,它有一个 BigDecimal price 字段。发送此 POJO 是为了响应两个 rest 调用:

  • 期望价格字段为数字值//所以@JsonSerialize 应该 不跑
  • 期望价格字段为字符串值//所以@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);

关于java - 如何通过注释有条件地使用自定义 JsonSerializer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52241567/

相关文章:

java - 如何在不显式配置策略的情况下获取对 SessionAuthenticationStrategy 的引用?

java - 泛型和静态内部类的问题

java - 如何在 hibernate 中将表列与另一个表列映射

java - 如何删除javafx折线图系列笔划点或调整其大小

java - 具有异步任务的 fragment 中的 ListView

javascript - 如何存储/记住从 ajax 调用中获取的数据?

java - 使用 Java 获取 JsonNode 的一部分并更新它,而无需修改主 JsonNode

spring - 如何在 Spring 中使用 FileSystemResource 正确下载文件?

java - mapred.Mapper 与 mapreduce.Mapper

java - 由 : There is no result type defined for type 'chain' mapped with name 'success' 引起