当前位置: 首页 > 知识库问答 >
问题:

避免使用Jackson自定义JsonSerializer和JsonGenerator序列化空字段

乜心思
2023-03-14

Jackson序列化到JSON有一些很好的特性,比如SerializationFeature.write_null_map_values,它允许您避免将null写入序列化对象

但是,如果我使用自定义的JsonSerializer,这个设置将被忽略,并且我被迫在对WriteStringField的所有调用中进行空检查。例如,我注册了一个自定义的JSONSerializer:

ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(CloudDocument.class, new ImportProductSerializer());

objectMapper.registerModule(simpleModule);

然后在ImportProductSerializer中,我不得不对要序列化的每个字段都进行空检查,这会变得丑陋和乏味:

private class ImportProductSerializer extends JsonSerializer<CloudDocument> {
    @Override
    public void serialize(CloudDocument value, 
        JsonGenerator gen, //Customize this?
        SerializerProvider serializers) throws Exception {
        gen.writeStartObject();
        gen.writeStringField("type", "add");

        //Null check here and every other field: gross!
        if(StringUtils.hasText(importProduct.getExtraListingSku1())) { 
            gen.writeStringField("extralistingsku1", importProduct.getExtraListingSku1());
        }
        gen.writeEndObject();
    }
}

我想采用的解决方案是让我的自定义JsonSerializer使用自定义JSONGenerator。serialize方法将JsonGenerator作为参数,我可以很容易地定义它,如下所示:

private class CustomGenerator extends JsonGenerator {

    @Override
    public JsonGenerator setCodec(ObjectCodec oc) {
        super.setCodec(oc);
    }


    @Override
    public void writeStringField(String fieldName, String value) throws IOException {
        if(value==null) return;
        super.writeStringField(fieldName.toLowerCase(), value);
    }
    .... //other methods implemented
}

但我不确定如何配置ObjectMapper来使用我的CustomGenerator实现。这种方法的好处是,我可以自定义writeField方法来执行空检查,并确保字段名订阅预期的命名约定,在本例中,这涉及将camelCase转换为lower_underscore。

有没有一种方法来配置通过调用ObjectMapper.WriteValue()实例化的JsonGenerator?

共有1个答案

利博远
2023-03-14

这个问题有点无限制,因为我不知道你到底尝试了什么;有多少工作是由自定义序列化程序完成的。通常,序列化器需要委派大量的处理,以最大限度地减少它们所做的工作量。

但是,如果您已经定义了一个自定义序列化器来处理包含字段的POJO(而不是序列化为JSON字符串或其他标量值的东西的自定义序列化器),那么是的,您确实需要处理自己的检查。这部分是因为有许多方法可以潜在地改变包含;不仅仅是SerializationFeature,还包括属性的@JsonFormat注释;当将控制委托给自定义序列化器时,没有办法透明地处理这一点。

因此,是的,如果您最终使用writeStringfield(),您确实需要检查默认包含设置并适当地省略write。

 类似资料:
  • 根据这个答案:https://stackoverflow.com/a/43342675/5810648 我编写了这样的序列化程序: 如果注释存在并且字段为,则Witch应该编写字符串“N/A”。但是方法仅对非空字段调用。 此外,我还尝试调用setNullValueSerializer: 有了这样的实施: 但没有结果。 如何以这种方式处理空字段? 使现代化 根据讨论:https://github.c

  • 问题内容: 我正在使用Flickr API 。调用该方法时,默认的JSON结果为: 我想将此响应解析为Java对象: JSON属性应按以下方式映射: 不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a 并从中获取值。 但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器? 这对我来说将是很明显的,

  • 问题内容: 我使用Jackson库将我的pojo对象序列化为表示形式。例如,我有A类和B类: 如果我要序列化类A中的对象,则有可能在序列化时获得递归。我知道我可以通过使用停止它。 是否可以通过深度级别限制序列化? 例如,如果级别为2,则序列化将以这种方式进行: 序列化一个,级别= 0(0 <2正常)->序列化 序列化ab,级别= 1(1 <2 ok)->序列化 序列化ABA,级别= 2(2 <2不

  • 序列化a,级别=0(0<2确定)->序列化 序列化A.B,级别=1(1<2确定)->序列化 序列化A.B.A,级别=2(2<2不为真)->停止 提前道谢。

  • 有没有一种方法可以使用Jackson JSON处理器来执行自定义字段级别的序列化?例如,我想让 注意,age=25被编码为数字,而favoritenumber=123被编码为字符串。Jackson将编组为一个数字。在这种情况下,我希望将favoriteNumber编码为字符串。

  • 有没有一种方法可以指定不同的序列化/反序列化JSON字段名,而不必显式地写出getter和setter方法,或许可以使用lombok getter和setter? 与此示例类似,下面的代码允许将传入的JSON反序列化为不同的POJO字段名。它还会使POJO字段名序列化为: 但这当然是不成立的。