本文介绍如何通过自定义序列化器和反序列化转换器,使 jackson 将 null set 序列化为 [],并将空数组 [] 反序列化为 null,同时保持非空集合的默认行为。
在 Jackson 中统一处理集合类(如 Set、List)的空值语义是一个常见但易被误解的需求:业务上常需将 null 集合序列化为 JSON 空数组 [](提升 API 兼容性与前端友好性),而将接收到的空数组 [] 显式还原为 null(以区分“未提供”与“明确提供空集合”)。直接继承 StdDeserializer
正确解法是分层协作:
以下为完整可运行示例(基于 Jackson 2.15+ 和 Spring Boot 常用工具类):
// 全局空集合处理器:自动为所有 Collection 类型启用 null ↔ []
public class EmptyAsNullCollectionJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public Object findNullSerializer(Annotated a) {
if (Collection.class.isAssignableFrom(a.getRawType())) {
return NullAsEmptyCollectionJsonSerializer.INSTANCE;
}
return super.findNullSerializer(a);
}
@Override
public Object findDeserializationConverter(Annotated a) {
if (List.class.isAssignableFrom(a.getRawType())) {
return EmptyListAsNullConverter.INSTANCE;
}
if (Set.class.isAssignableFrom(a.getRawType())) {
return EmptySetAsNullConverter.INSTANCE;
}
return super.findDeserializationConverter(a);
}
}
// 序列化器:所有 null 集合 → []
class NullAsEmptyCollectionJsonSerializer extends JsonSerializer使用方式一:全局配置(推荐)
var mapper = JsonMapper.builder()
.enable(SerializationFeature.INDENT_OUTPUT)
.annotationIntrospector(new EmptyAsNullCollectionJacksonAnnotationIntrospector())
.build();使用方式二:字段级注解(更灵活)
public class CollectionsPojo {
@JsonSerialize(nullsUsing = NullAsEmptyCollectionJsonSerializer.class)
@JsonDeserialize(converter = EmptySetAsNullConverter.class)
private Set tags;
@JsonSerialize(nullsUsing = NullAsEmptyCollectionJsonSerializer.class)
@JsonDeserialize(converter = EmptyListAsNullConverter.class)
private List ids;
} ✅ 效果验证:
⚠️ 注意事项:
此方案兼顾简洁性、可维护性与扩展性,无需侵入业务代码,即可统一治理集合空值语义。