【问题标题】:Jackson null list to empty array serialization杰克逊空列表到空数组序列化
【发布时间】:2026-02-13 22:15:01
【问题描述】:

我想将空列表序列化为空数组。

所以给定:

class MyBean { List values; }

并且给定一个值为 null 的实例,它应该被序列化为:

{ "values": [] }

我希望这是所有类中所有列表的全局行为。我不想为类添加任何注释或特定处理。

我已阅读我发现的所有相关问题,但无法提出任何可行的方法。似乎我尝试为 List 类注册的任何自定义序列化程序都没有启动。

如果您的项目有此工作,请告诉我您是如何做到的。

【问题讨论】:

    标签: java serialization jackson


    【解决方案1】:

    在这种情况下,您需要自定义 JacksonAnnotationIntrospector 类。序列化null-s,默认情况下Jackson使用com.fasterxml.jackson.databind.ser.std.NullSerializer类。您可以扩展默认的自省类并覆盖 findNullSerializer

    见下例:

    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializerProvider;
    import com.fasterxml.jackson.databind.introspect.Annotated;
    import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
    import com.fasterxml.jackson.databind.ser.std.StdSerializer;
    
    import java.io.IOException;
    import java.util.List;
    
    public class Main {
    
        public static void main(String[] args) throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            mapper.setAnnotationIntrospector(new EmptyArrayJacksonAnnotationIntrospector());
            mapper.writeValue(System.out, new ListWrapper());
        }
    }
    
    class EmptyArrayJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector {
    
        @Override
        public Object findNullSerializer(Annotated a) {
            if (List.class.isAssignableFrom(a.getRawType())) {
                return ArrayNullSerializer.INSTANCE;
            }
            return super.findNullSerializer(a);
        }
    }
    
    final class ArrayNullSerializer extends StdSerializer<Object> {
    
        public static final ArrayNullSerializer INSTANCE = new ArrayNullSerializer();
    
        protected ArrayNullSerializer() {
            super(Object.class);
        }
    
        @Override
        public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeStartArray();
            gen.writeEndArray();
        }
    }
    
    class ListWrapper {
    
        private List values;
    
        public List getValues() {
            return values;
        }
    
        public void setValues(List values) {
            this.values = values;
        }
    }
    

    上面的代码打印:

    {"values":[]}
    

    【讨论】:

    • 第一次尝试就成功了!谢谢!我可能应该将此答案链接到其他无助于我前进的相关问题。
    • @Raipe,我很高兴听到这个消息。如果您认为这对其他人有帮助,您可以将我在 cmets 中的答案添加到您在开始时发现的其他问题中。
    • 如果您有任何关于为什么这是要使用的解决方案的其他信息,我很乐意学习。通过注释检查器执行此操作听起来很奇怪(虽然有效)。
    • @Raipe,这个解决方案没有什么奇怪的。您可以使用@JsonSerialise 注释定义NullSerialiser,但您明确写了,您不想这样做。因此,我们可以欺骗Jackson 并强制它始终使用我们为List 类型的自定义实现。 JacksonAnnotationIntrospector 是一个读取注解并配置给定对象序列化或反序列化方式的类。