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

如何自动序列化嵌套空对象?Jackson实现完整空结构输出

问题:Jackson序列化生成完整嵌套空结构需求

现有Java类结构

public class A implements Serializable {
    String prop1;
    String prop2;
    B prop3;
}

public class B implements Serializable {
    String nestedProp4;
    String nestedProp5;
    C nestedProp6;
}

public class C implements Serializable {
    String nestedProp7;
}

当前序列化代码

A obj = new A();
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.valueToTree(obj);

实际序列化结果

{
    "prop1": null,
    "prop2": null,
    "prop3": null
}

期望序列化结果

{
    "prop1": null,
    "prop2": null,
    "prop3": {
        "nestedProp4": null,
        "nestedProp5": null,
        "nestedProp6": {
            "nestedProp7": null
        }
    }
}

核心需求

是否存在无需自行编写反射代码或手动设置属性默认值的自动方式/类级注解实现该序列化?由于类包含大量属性,拒绝为每个属性添加注解,仅接受类级注解或全局配置。


解决方案

Jackson默认不会自动实例化null的嵌套对象并序列化其空属性,要实现需求可通过全局配置+类级注解结合的方式,无需逐个属性添加注解:

步骤1:确保null属性被序列化

有两种方式可选,二选一即可:

  • 全局配置(推荐,无需修改现有类)
    在创建ObjectMapper时设置全局属性包含规则:
    mapper.setDefaultPropertyInclusion(JsonInclude.Include.ALWAYS);
    
  • 类级注解
    为所有需要生成完整空结构的类(A、B、C)添加类级注解:
    @JsonInclude(JsonInclude.Include.ALWAYS)
    public class A implements Serializable { ... }
    // B、C类同理添加该注解
    

步骤2:自定义序列化扩展,自动实例化null嵌套对象

Jackson原生没有自动实例化null嵌套对象的配置,需要通过BeanSerializerModifier扩展序列化逻辑,自动将null的自定义类属性实例化为空对象再序列化:

  1. 实现自定义BeanSerializerModifier:
public class EmptyObjectSerializerModifier extends BeanSerializerModifier {
    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
        for (BeanPropertyWriter writer : beanProperties) {
            Class<?> propType = writer.getType().getRawClass();
            // 仅处理自定义的可序列化类(排除基础类型、String、集合、Map等)
            if (!propType.isPrimitive() 
                && !String.class.isAssignableFrom(propType)
                && !Collection.class.isAssignableFrom(propType)
                && !Map.class.isAssignableFrom(propType)) {
                // 为null属性设置自定义序列化器,自动实例化空对象
                writer.assignNullSerializer(new JsonSerializer<Object>() {
                    @Override
                    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                        try {
                            Object emptyInstance = propType.getDeclaredConstructor().newInstance();
                            serializers.defaultSerializeValue(emptyInstance, gen);
                        } catch (Exception e) {
                            // 无法实例化时回退到输出null
                            gen.writeNull();
                        }
                    }
                });
            }
        }
        return beanProperties;
    }
}
  1. 配置ObjectMapper注册该扩展:
A obj = new A();
ObjectMapper mapper = new ObjectMapper();
// 关闭空Bean序列化报错(空对象的所有属性都是null时需要)
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 设置全局属性包含规则(若已用类级注解可省略此行)
mapper.setDefaultPropertyInclusion(JsonInclude.Include.ALWAYS);
// 注册自定义序列化扩展
mapper.registerModule(new SimpleModule().setSerializerModifier(new EmptyObjectSerializerModifier()));

JsonNode node = mapper.valueToTree(obj);

通过以上配置,序列化时会自动将所有null的自定义类属性实例化为空对象,并输出其所有null属性,最终生成你需要的完整嵌套结构。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:10:09