
本文详解如何配置 Jackson 2.x 的 ObjectMapper,使其在序列化时保留空字符串 ""(而非跳过字段),重点纠正 setSerializationInclusion(Include.NON_EMPTY) 导致空字符串被过滤的根本原因,并提供安全、标准的配置方案。
本文详解如何配置 jackson 2.x 的 `objectmapper`,使其在序列化时保留空字符串 `""`(而非跳过字段),重点纠正 `setserializationinclusion(include.non_empty)` 导致空字符串被过滤的根本原因,并提供安全、标准的配置方案。
在使用 Jackson 进行 JSON 序列化时,若发现空字符串字段(如 "number": "")在输出中被完全省略(例如 { "id": 2 } 中缺失 number 字段),这通常并非反序列化行为异常,而是序列化阶段的包含策略(Serialization Inclusion)配置所致。
关键问题出在这一行配置:
objectMapper.setSerializationInclusion(Include.NON_EMPTY);
Include.NON_EMPTY 的语义是:跳过值为“空”的属性——对 String 类型而言,""(空字符串)即被视为“空”,因此该字段在序列化时被主动排除。这与 Include.NON_NULL(仅跳过 null)有本质区别,且不可通过 ACCEPT_EMPTY_STRING_AS_NULL_OBJECT(该特性仅影响反序列化,即将 "" 当作 null 处理)来修复。
✅ 正确解决方案是:移除或调整序列化包含策略,显式允许空字符串参与序列化。推荐以下两种稳健方式:
方案一:仅排除 null,保留空字符串(最常用)
private static void configureObjectMapper(ObjectMapper objectMapper) {
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setDateFormat(new SimpleDateFormat(DATE_PATTERN));
// ✅ 关键修正:只忽略 null,不忽略空字符串
objectMapper.setSerializationInclusion(Include.NON_NULL);
}
方案二:精细控制——按字段级别指定序列化策略(推荐用于复杂场景)
public static class PhoneNumber {
private int id;
@JsonInclude(Include.NON_NULL) // 对 id 不生效(int 不可能为 null),但可加
private String number;
// 构造函数、getter、setter...
}
或使用注解明确允许空字符串:
@JsonInclude(Include.ALWAYS) // 强制序列化该字段(含 "" 和 null) private String number;
⚠️ 注意事项:
-
DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT = true仅作用于反序列化(即 JSON → Java 对象),它会让 Jackson 把""反序列化为null,完全不解决序列化时丢弃空字符串的问题; -
Include.NON_EMPTY对集合、Map、数组、CharSequence(含 String)均生效,务必确认业务是否真需全局过滤空字符串; - 若必须全局启用
NON_EMPTY但又需保留某些空字符串字段,请改用@JsonInclude(Include.ALWAYS)或自定义JsonSerializer。
? 总结:空字符串在序列化中消失,根源是 Include.NON_EMPTY 的语义设计。修复核心在于——明确区分“不传 null”和“不传空字符串”的业务需求,并选用匹配的 @JsonInclude 策略。优先使用 NON_NULL + 字段级 @JsonInclude(Include.ALWAYS) 组合,兼顾简洁性与可控性。











