如何通过Jackson便捷序列化与反序列化含空键的Map
Spring Boot中ObjectMapper处理Map空键的序列化与反序列化
需求背景
使用Spring Boot自动配置的ObjectMapper,实现所有泛型Map的null键双向序列化/反序列化:
- 序列化时:Map的null键转为字符串
"null" - 反序列化时:字符串
"null"转为Map的null键 - 核心要求:不影响
ObjectMapper对其他类型的原有处理逻辑,所有配置集中在一处,不能使用字段注解或手动创建new ObjectMapper()。
解决方案
通过Spring Boot提供的Jackson2ObjectMapperBuilderCustomizer扩展自动配置的ObjectMapper,分别处理序列化和反序列化逻辑:
1. 序列化处理(Null键转"null"字符串)
你之前实现的自定义NullKeySerializer是可行的,不会破坏非Map类型的序列化——因为该序列化器仅在Jackson处理Map的null键时才会被调用,其他类型的序列化逻辑完全保留原有行为。
官方目前没有非废弃的内置NullKeySerializer实现,自定义是最简洁的方案。
2. 反序列化处理("null"字符串转Null键)
需要自定义KeyDeserializer,并注册到全局模块中,实现对所有泛型Map的键处理:
完整配置代码
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.KeyDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.io.IOException; @Configuration public class JacksonMapNullKeyConfig { @Bean public Jackson2ObjectMapperBuilderCustomizer customizeMapNullKeyHandling() { return builder -> { // 配置序列化:Map的null键输出为"null"字符串 builder.serializerProvider(provider -> { provider.setNullKeySerializer(new JsonSerializer<>() { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeFieldName("null"); } }); return provider; }); // 配置反序列化:将"null"字符串转为Map的null键 SimpleModule nullKeyModule = new SimpleModule(); nullKeyModule.addKeyDeserializer(Object.class, new KeyDeserializer() { @Override public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { return "null".equals(key) ? null : key; } }); builder.modules(nullKeyModule); }; } }
说明
- 采用
Jackson2ObjectMapperBuilderCustomizer是Spring Boot官方推荐的扩展方式,不会替换原有自动配置的ObjectMapper,仅做逻辑增强。 - 反序列化时注册的
KeyDeserializer针对Object.class,意味着所有类型的Map键(如String、Integer等)都会被处理,完美支持泛型Map。 - 所有配置集中在一个
@Configuration类中,无需修改业务代码或添加字段注解。
内容的提问来源于stack exchange,提问作者amseager
相关产品推荐
相关产品推荐

