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

Quarkus从Json-B迁Jackson,如何配置实现对象键Map的Json-B式序列化?

Jackson通用配置实现Json-B风格的对象键Map序列化

要让Jackson对以对象为键的Map输出和Json-B一致的序列化结果,你可以通过注册全局自定义Module的方式实现通用解决方案,无需针对每个Map单独编写序列化器:

实现步骤

1. 自定义Map序列化Module

创建一个SimpleModule,替换默认的Map序列化逻辑,将非字符串键的Map序列化为包含key和value字段的对象数组:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.MapSerializer;

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

public class JsonBMapModule extends SimpleModule {
    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.addBeanSerializerModifier(new BeanSerializerModifier() {
            @Override
            public JsonSerializer<?> modifyMapSerializer(SerializationConfig config, MapType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer) {
                // 仅对非String类型键的Map应用自定义序列化逻辑
                if (!valueType.getKeyType().getRawClass().equals(String.class)) {
                    return new JsonBMapSerializer((MapSerializer) serializer);
                }
                return serializer;
            }
        });
    }

    private static class JsonBMapSerializer extends MapSerializer {
        public JsonBMapSerializer(MapSerializer src) {
            super(src);
        }

        @Override
        public void serialize(Map<?, ?> value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeStartArray();
            for (Map.Entry<?, ?> entry : value.entrySet()) {
                gen.writeStartObject();
                // 序列化key字段
                gen.writeFieldName("key");
                provider.defaultSerializeValue(entry.getKey(), gen);
                // 序列化value字段
                gen.writeFieldName("value");
                provider.defaultSerializeValue(entry.getValue(), gen);
                gen.writeEndObject();
            }
            gen.writeEndArray();
        }
    }
}

2. 在Quarkus中注册Module

通过ContextResolver自定义ObjectMapper,将上述Module全局注册:

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;
import com.fasterxml.jackson.databind.ObjectMapper;

@Provider
@ApplicationScoped
public class ObjectMapperConfig implements ContextResolver<ObjectMapper> {
    private final ObjectMapper objectMapper;

    public ObjectMapperConfig() {
        objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JsonBMapModule());
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return objectMapper;
    }
}

效果验证

配置完成后,你的Map<Car, String>接口返回结果会和Json-B完全一致:

[
    {
        "key": {
            "color": "Red",
            "id": 1
        },
        "value": "First"
    }
]

该方案的优势是全局生效,所有以非String对象为键的Map都会自动采用Json-B风格的序列化,无需修改业务代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:00:21