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

如何基于Jackson实现Map的条件化自定义序列化?

问题原因

原代码的错误出在通过BeanSerializerModifier获取的默认MapSerializer未被正确初始化,导致序列化时keySerializer为null,引发空指针异常。直接包装并调用该序列化器的serialize方法时,缺少了必要的上下文配置。

修正方案

直接为MyMap注册自定义序列化器,避免使用SerializerModifier,同时在序列化逻辑中:

  • 当name为"magic name"时,输出指定字符串;
  • 否则,委托Jackson的默认HashMap序列化器处理,确保所有Map序列化的细节(如键值处理、嵌套对象序列化)都能正确执行。
修正后的完整代码
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.Getter;
import lombok.Setter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class MapParseTest {
    private final ObjectMapper mapper;

    public MapParseTest() {
        mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        // 直接注册MyMap的自定义序列化器
        module.addSerializer(MyMap.class, new MyMapSerializer());
        mapper.registerModule(module);
    }

    public void doTest() throws IOException {
        MyMap map1 = new MyMap();
        MyMap map2 = new MyMap();

        map1.setName("shtame");
        map2.setName("magic name");

        map1.put("First", 1);
        map1.put("Second", "Two");
        map1.put("Third", map2);

        map2.put("Eleventh", 11);
        map2.put("Twelfth", "12");

        String result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map1);
        System.out.println(result);
    }

    public static void main(String[] args) throws IOException {
        MapParseTest test = new MapParseTest();
        test.doTest();
    }

    @Setter
    @Getter
    public static class MyMap extends HashMap<String, Object> {
        private String name;
    }

    public static class MyMapSerializer extends JsonSerializer<MyMap> {
        @Override
        public void serialize(MyMap value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            String className = value.getName();
            // 检查name是否符合条件,增加null判断避免空指针
            if (className != null && className.equalsIgnoreCase("magic name")) {
                gen.writeString("magic string");
            } else {
                // 委托Jackson默认的HashMap序列化器处理
                JsonSerializer<Object> mapSerializer = provider.findValueSerializer(HashMap.class, null);
                mapSerializer.serialize(value, gen, provider);
            }
        }
    }
}
输出结果

运行上述代码后,将得到符合期望的输出(注:HashMap不保证键值顺序,若需固定顺序可改为继承LinkedHashMap):

{
  "First" : 1,
  "Second" : "Two",
  "Third" : "magic string"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:49:57