Jackson序列化Map<String,Object>字符串值双引号重复问题求助
我之前碰到过完全一样的情况!这个重复双引号的问题,本质是你的第三方库已经把Map里的String值提前做了JSON序列化——比如原本的value被处理成了带双引号的"value"字符串,Jackson默认会把它当成普通文本再转义一次双引号,最终就出现了""value""的诡异结果。
不用写自定义类型检查逻辑的话,这几个方案可以快速解决:
方案1:给Map字段加@JsonRawValue注解(针对固定字段)
如果这个Map<String, Object>是某个实体类的固定字段,直接给它加上@JsonRawValue注解就行。这个注解会告诉Jackson:直接把Map里的值作为原生JSON内容输出,不要做额外转义。
示例代码:
public class YourBusinessClass { // 给Map字段添加注解 @JsonRawValue private Map<String, Object> dataMap; // 省略getter/setter }
这样当Map里的String值是已经序列化好的JSON格式时,Jackson会直接把它嵌入最终的JSON结构里,不会重复转义双引号。
方案2:将预先序列化的字符串转成JsonNode再放入Map(通用方案)
如果你的Map是动态生成的,或者不想修改实体类,更通用的方法是:把第三方库返回的带双引号的字符串,先转成Jackson的JsonNode对象,再放入Map中。Jackson序列化JsonNode时会自动识别它的JSON类型,直接输出正确的格式。
示例代码:
// 假设从第三方库拿到预先序列化的字符串 String preSerializedStr = "\"value\""; // 第三方返回的已经带双引号的内容 // 转成JsonNode再放入Map JsonNode jsonNode = OBJECT_MAPPER.readTree(preSerializedStr); yourMap.put("key", jsonNode); // 再序列化整个对象 String resultJson = OBJECT_MAPPER.writeValueAsString(yourObject);
这个方法完全不需要类型检查,readTree会自动解析合法的JSON字符串(不管是字符串、数字还是复杂对象),序列化后就是正常的{"key": "value"}。
方案3:全局关闭双引号转义(不推荐,慎用)
还有一种极端方法是全局配置Jackson,取消对双引号的转义,但这会影响所有字符串的序列化,可能导致JSON格式不合法(比如字符串里本来就有需要转义的双引号),所以只在特殊场景下使用:
OBJECT_MAPPER.getFactory().setCharacterEscapes(new CharacterEscapes() { @Override public int[] getEscapeCodesForAscii() { int[] escapes = StandardCharacterEscapes.INSTANCE.getEscapeCodesForAscii(); // 取消双引号的转义处理 escapes['"'] = CharacterEscapes.ESCAPE_NONE; return escapes; } @Override public SerializableString getEscapeSequence(int ch) { return StandardCharacterEscapes.INSTANCE.getEscapeSequence(ch); } });
推荐方案
优先选方案2,它通用且安全,不需要修改实体类,也不会影响其他字段的序列化;如果是固定的实体类字段,方案1更简洁。
内容的提问来源于stack exchange,提问作者Toseef Zafar

