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
相关产品推荐
相关产品推荐

