使用Jackson自定义序列化时遭遇类型转换异常问题求助
嘿,这个问题我之前排查过类似的,咱们一步步拆解解决:
问题核心原因
你遇到的com.fasterxml.jackson.databind.JsonMappingException: java.lang.String cannot be cast to java.util.Map错误,加上自定义序列化器的serialize方法根本没执行,本质是Jackson错误地把你的Map序列化器绑定到了String类型对象上,而非预期的Map类型。
大概率是以下两种情况之一:
1. 先确认传入对象的实际类型
先在调用objectMapper.writeValueAsString(loginInfoJSON)前加一行调试代码:
System.out.println("loginInfoJSON类型:" + loginInfoJSON.getClass().getName());
如果输出是java.lang.String,那问题就找到了——你要序列化的对象本身就是String,不是Map!Jackson会强行把String转成Map来匹配你的序列化器,自然抛出类型转换异常。
这种情况的解决办法:先把String转成Map,再序列化:
// 先将String解析为Map Map<String, Object> loginInfoMap = objectMapper.readValue(loginInfoJSON, new TypeReference<Map<String, Object>>() {}); // 再序列化Map String result = objectMapper.writeValueAsString(loginInfoMap);
2. 检查序列化器的注册/绑定方式
如果loginInfoJSON确实是Map类型,那问题出在序列化器的注册上:
- 如果你用了
@JsonSerialize(using = ItemSerializer.class)注解,检查是不是误把它加到了String类型的字段上? - 如果是全局注册序列化器,确认注册的目标类型是Map,而不是String:
// ❌ 错误写法:把序列化器绑定到了String.class objectMapper.registerModule(new SimpleModule().addSerializer(String.class, new ItemSerializer())); // ✅ 正确写法:绑定到Map.class(或具体实现类如HashMap.class) objectMapper.registerModule(new SimpleModule().addSerializer(Map.class, new ItemSerializer()));
3. 优化自定义序列化器的泛型(可选)
你的序列化器定义是JsonSerializer<Map<String, Object>>,可以调整为更通用的泛型,避免泛型擦除导致的匹配问题:
public class ItemSerializer extends JsonSerializer<Map<?, ?>> { @Override public void serialize(Map<?, ?> value, JsonGenerator gen, SerializerProvider serializers) throws IOException { // 这里写你的自定义序列化逻辑 gen.writeStartObject(); for (Map.Entry<?, ?> entry : value.entrySet()) { gen.writeObjectField(entry.getKey().toString(), entry.getValue()); } gen.writeEndObject(); } }
验证步骤
- 确认
loginInfoJSON是Map实例; - 确认序列化器绑定到了正确的类型;
- 重新运行代码,应该就能正常进入
serialize方法执行自定义逻辑了。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

