如何在不创建额外类时将Java Map序列化为指定结构的JSON?
用Jackson调整单键值对Map的序列化/反序列化格式
可以通过自定义**序列化器(JsonSerializer)和反序列化器(JsonDeserializer)**实现,完全不需要额外创建实体类,同时保证反序列化后仍为Map类型。
实现步骤:
- 自定义序列化器,将单条目Map转换为
{"key":"xxx", "value":"xxx"}格式:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.util.Map; public class SingleEntryMapSerializer extends JsonSerializer<Map<String, String>> { @Override public void serialize(Map<String, String> map, JsonGenerator gen, SerializerProvider serializers) throws IOException { // 只处理单条目Map,多条目可按需求调整逻辑 if (map.size() != 1) { // 多条目时按默认逻辑序列化,也可抛出异常提示仅支持单条目 serializers.defaultSerializeValue(map, gen); return; } Map.Entry<String, String> entry = map.entrySet().iterator().next(); gen.writeStartObject(); gen.writeStringField("key", entry.getKey()); gen.writeStringField("value", entry.getValue()); gen.writeEndObject(); } }
- 自定义反序列化器,将
{"key":"xxx", "value":"xxx"}格式转换回Map:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; import java.util.Collections; import java.util.Map; public class SingleEntryMapDeserializer extends JsonDeserializer<Map<String, String>> { @Override public Map<String, String> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.getCodec().readTree(p); String key = node.get("key").asText(); String value = node.get("value").asText(); return Collections.singletonMap(key, value); // 若需要可变Map,可替换为new HashMap<>(Map.of(key, value)) } }
- 将自定义序列化/反序列化器注册到ObjectMapper:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import java.util.Collections; import java.util.Map; public class Main { public static void main(String[] args) throws Exception { ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); // 注册针对Map<String,String>的自定义序列化/反序列化器 module.addSerializer(Map.class, new SingleEntryMapSerializer()); module.addDeserializer(Map.class, new SingleEntryMapDeserializer()); mapper.registerModule(module); // 测试序列化 Map<String, String> map = Collections.singletonMap("dummyKey", "dummyValue"); String json = mapper.writeValueAsString(map); System.out.println(json); // 输出: {"key":"dummyKey","value":"dummyValue"} // 测试反序列化 Map<String, String> deserializedMap = mapper.readValue(json, Map.class); System.out.println(deserializedMap.get("dummyKey")); // 输出: dummyValue } }
补充说明:
- 如果需要处理非单条目Map,可修改序列化器逻辑,比如对多条目Map按默认方式序列化,或者抛出
IllegalArgumentException提示仅支持单条目。 - 若要支持更通用的Map类型(比如
Map<Object, Object>),可调整序列化器/反序列化器的泛型参数。
内容的提问来源于stack exchange,提问作者Polyphonic Mobius
相关产品推荐
相关产品推荐

