
Jackson 默认将 Optional 的空值序列化为 null,需配置 @JsonInclude(JsonInclude.Include.NON_ABSENT) 或改用非 Optional 的字段设计,才能实现对空 Optional 字段(如 Optional.empty())的完全忽略。
jackson 默认将 `optional` 的空值序列化为 `null`,需配置 `@jsoninclude(jsoninclude.include.non_absent)` 或改用非 `optional` 的字段设计,才能实现对空 `optional` 字段(如 `optional.empty()`)的完全忽略。
在使用 Jackson 处理 Java 8+ 的 Optional 类型时,一个常见误区是期望 JsonInclude.Include.NON_NULL 能自动跳过 Optional.empty()——但事实并非如此。因为 Optional.empty() 是一个非 null 的对象实例,它不等于 null,因此 NON_NULL 策略对其无效,最终仍会输出 "secondName": null。
✅ 正确解决方案是使用 JsonInclude.Include.NON_ABSENT:
该策略专为“缺席值”(absent value)设计,Jackson 的 Jdk8Module 会将 Optional.empty() 映射为 ABSENT,从而在序列化时彻底排除该字段。
✅ 正确配置示例
// 启用 Jdk8Module 并设置全局包含策略
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jdk8Module());
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT); // 关键:替换 NON_NULL
// 或对特定字段加注解(更灵活)
class Employee {
private String firstName;
private String secondName;
@JsonInclude(JsonInclude.Include.NON_ABSENT)
public Optional<String> getFirstName() {
return Optional.ofNullable(firstName);
}
@JsonInclude(JsonInclude.Include.NON_ABSENT)
public Optional<String> getSecondName() {
return Optional.ofNullable(secondName);
}
// setters...
}此时,当 secondName 为 null 时,getSecondName() 返回 Optional.empty(),序列化结果即为:
{"firstName":"foo"}⚠️ 重要提醒:
-
NON_ABSENT仅对 Jackson 认可的“可选类型”(如Optional,OptionalInt,OptionalLong等)生效,前提是已注册Jdk8Module; - 不建议将
Optional作为实体类的字段访问器返回类型(如本例中的 getter)。根据 Java 官方文档,Optional主要用于方法返回值以明确表达“无结果”,而非作为属性封装器——这既违背其设计初衷,也增加序列化/反序列化的复杂性; - 更推荐的实践是:保持字段为普通类型(如
String),在业务逻辑中按需构造Optional,例如Optional.ofNullable(employee.getFirstName())。
? 总结:若必须使用 Optional getter,请务必搭配 NON_ABSENT + Jdk8Module;但长期来看,重构为非 Optional 的 POJO 字段设计,才是清晰、高效且符合 Jackson 与 Java 生态惯例的方案。

















