如何让Jackson将指定静态对象NULL_VALUE序列化为null?
问题描述
我尝试序列化一个包含无法修改对象的列表,该列表引用了一个静态对象:
final public static Object NULL_VALUE = new Object() { public String toString() { return "null"; }};
如何配置Jackson将NULL_VALUE对象序列化为null?我尝试了以下自定义序列化器:
public class NullValueSerializer extends StdSerializer<Object> { public NullValueSerializer() { super(Object.class); } @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == Jsonata.NULL_VALUE) { gen.writeNull(); } else { gen.writePOJO(value); } } }
本以为此方案可行,但显然出现了StackOverflowError,原因是序列化器递归调用自身。我未找到文档中有相关解决方法,请问是否存在将该值序列化为null的可行方案?
可行解决方案
递归问题的核心是调用gen.writePOJO(value)时,Jackson会再次使用当前绑定的NullValueSerializer处理对象,触发无限递归。以下是几种可行的解决思路:
1. 调用默认序列化器处理非目标对象
避免直接使用writePOJO,转而获取Jackson原生的默认序列化器来处理非NULL_VALUE的对象:
public class NullValueSerializer extends StdSerializer<Object> { public NullValueSerializer() { super(Object.class); } @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == Jsonata.NULL_VALUE) { gen.writeNull(); } else { // 获取Object类型的默认序列化器 JsonSerializer<Object> defaultSerializer = serializers.findValueSerializer(Object.class, null); // 绕过当前序列化器执行序列化,避免递归 defaultSerializer.unwrappingSerializer(null).serialize(value, gen, serializers); } } }
2. 针对具体类型注册序列化器
由于NULL_VALUE是匿名内部类的实例,可直接针对该具体类型注册序列化器,而非覆盖整个Object类的序列化逻辑,从根源避免递归:
// 获取NULL_VALUE的实际类型 Class<?> nullValueType = Jsonata.NULL_VALUE.getClass(); // 注册自定义序列化器 ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(nullValueType, new StdSerializer<Object>(nullValueType) { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeNull(); } }); mapper.registerModule(module);
这种方式更高效,仅对NULL_VALUE实例生效,不影响其他对象的正常序列化流程。
3. 通过BeanSerializerModifier全局拦截
如果需要全局范围内处理该对象,可使用BeanSerializerModifier拦截序列化过程:
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new SimpleModule() { @Override public void setupModule(SetupContext context) { super.setupModule(context); context.addBeanSerializerModifier(new BeanSerializerModifier() { @Override public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) { return new JsonSerializer<Object>() { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == Jsonata.NULL_VALUE) { gen.writeNull(); } else { // 调用原序列化器处理其他对象 serializer.serialize(value, gen, serializers); } } }; } }); } });
内容的提问来源于stack exchange,提问作者alturkovic
相关产品推荐
相关产品推荐

