java - 如何 JSON 序列化空值而不是 jackson 的空值?

标签 java json jackson

Jackson ObjectMapper 有一个特性允许删除空值:

class Car {
   Optional<String> ownerName;
   String manufacturer;

   public Optional<String> getOwnerName() { return ownerName; }
   public String getManufacturer() { return manufacturer; }
}

Car batMobile = new Car();
batMobile.owner = Optional.of("Batman");
batMobile.manufacturer = null;

Car stolenCar = new Car();
stolenCar.owner = Optional.empty();
stolenCar.manufacturer = "Tesla";

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_ABSENT);

mapper.writeValueAsString(batMobile);
/*
{
  "ownerName": "Batman"
}
*/
mapper.writeValueAsString(stolenCar);
/*
{
  "manufacturer": "Tesla"
}
*/

我想要的是删除 Optional.empty 值,但保留空值:

mapper.writeValueAsString(batMobile);
/*
{
  "ownerName": "Batman",
  "manufacturer": null
}
*/
mapper.writeValueAsString(stolenCar);
/*
{
  "manufacturer": "Tesla"
}
*/

我希望这可以在全局范围内应用,而不需要对 DTO 进行任何注释。

最佳答案

如果您使用 java.util.Optional确保您已注册 com.fasterxml.jackson.datatype.jdk8.Jdk8Module提供额外的序列化器和反序列化器的模块。

在您的情况下,最简单的方法是在属性级别上使用注释:

class Car {

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    Optional<String> ownerName;

    @JsonInclude
    String manufacturer;

    //getters, setters
}

默认值为 Include.ALWAYS在您的情况下应该使用它。

如果您想在全局范围内执行此操作,则需要实现自定义过滤器并手动检查所有案例。简单的例子:
class CustomFilter {

    @Override
    public boolean equals(Object obj) {
        // return false to keep value in response
        // return true to filter out value from response
        if (obj == null) {
            return false;
        }
        if (obj instanceof Optional) {
            Optional opt = (Optional) obj;
            return !opt.isPresent();
        }
        //other cases if needed

        return false;
    }
}

您可以按如下方式注册:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(new Jdk8Module());
mapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.CUSTOM, JsonInclude.Include.CUSTOM, CustomFilter.class, CustomFilter.class));

如果这不是您想要的,您需要设置全局最合适的值,并为给定的属性设置另一个值。如果不能修改DTO类,您可以随时使用 MixIn特征。

关于java - 如何 JSON 序列化空值而不是 jackson 的空值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61286232/

相关文章:

java - GSON列表列表

javascript - 扎 PIL 代码 : Transform String to Array javascript

jackson - Kotlin 枚举类的值属性中的 @JsonValue 注释

java - 属性 DTO 中格式化日期的符号 Gson

Java Swing 双击+拖动以选择整个单词

java - 用于可选前导正斜杠的正则表达式

java - 使用反射从函数中删除同步关键字

java - 如何重写此方法以删除多余的 if 语句?

php - 带有 json 响应的 Symfony 操作

java - Jackson:反序列化接口(interface)集的实例化子类(yml)