You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jackson将单元素List属性序列化为单个对象?

Jackson实现List单元素自动序列化为单个对象的方案

实现思路

自定义Jackson序列化器,对List类型字段做长度判断,长度为1时直接序列化第一个元素,其他情况保持默认数组行为。

步骤1:定义通用单元素List序列化器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.util.List;

public class SingleElementListSerializer extends StdSerializer<List<?>> {

    // 无参构造必须保留,Jackson序列化时通过反射调用
    public SingleElementListSerializer() {
        this(null);
    }

    public SingleElementListSerializer(Class<List<?>> t) {
        super(t);
    }

    @Override
    public void serialize(List<?> value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // null值直接输出null,可根据需求修改为输出空数组
        if (value == null) {
            gen.writeNull();
            return;
        }
        switch (value.size()) {
            case 0:
                // 空列表输出空数组,可根据需求修改为输出null
                gen.writeStartArray();
                gen.writeEndArray();
                break;
            case 1:
                // 单个元素直接序列化对应对象
                provider.defaultSerializeValue(value.get(0), gen);
                break;
            default:
                // 多个元素序列化为标准数组格式
                gen.writeStartArray();
                for (Object item : value) {
                    provider.defaultSerializeValue(item, gen);
                }
                gen.writeEndArray();
        }
    }
}

步骤2:绑定序列化器

两种绑定方式可按需选择:

方式1:仅对指定字段生效(推荐,粒度更灵活)

直接在POJO的bars字段上加@JsonSerialize注解指定序列化器即可:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.util.List;

public class Foo {
   private String name;

   @JsonSerialize(using = SingleElementListSerializer.class)
   private List<Bar> bars;
   
   // 省略getters、setters
}

方式2:全局对所有List类型生效

将序列化器注册到ObjectMapper,所有List类型字段都会自动应用该规则:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.util.List;

ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
// 注册全局List序列化器
module.addSerializer(List.class, new SingleElementListSerializer());
objectMapper.registerModule(module);

反序列化适配

如果后续需要把序列化后的JSON反序列回Java对象,需要开启ACCEPT_SINGLE_VALUE_AS_ARRAY配置,支持单个对象自动转换为List:

import com.fasterxml.jackson.databind.DeserializationFeature;

objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

效果验证

bars字段值序列化结果
null"bars": null
空列表"bars": []
仅1个Bar元素"bars": {"bar属性":"对应值"}
多个Bar元素"bars": [{},{}]

内容的提问来源于stack exchange,提问作者andrewdleach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 21:39:02