在使用jackson处理json时遇到了反斜杠相关的问题。比如我们从数据库或文件中读到了这样的一个json字符串:
1 |
{"text":"Hello \World!"} |
可以看到在World前面有一个反斜杠。因为这个反斜杠,JetBrains IDEA会提示这是一个错误的字符串,使用jakcson处理这个json字符串时也会报错,错误信息如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Unrecognized character escape 'W' (code 87) at [Source: (String)"{"text":"Hello \World!"}"; line: 1, column: 18] at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1840) at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:712) at com.fasterxml.jackson.core.base.ParserBase._handleUnrecognizedCharacterEscape(ParserBase.java:1031) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._decodeEscaped(ReaderBasedJsonParser.java:2545) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._finishString2(ReaderBasedJsonParser.java:2066) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._finishString(ReaderBasedJsonParser.java:2039) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.getText(ReaderBasedJsonParser.java:294) at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:672) at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173) at org.chobit.calf.MyApp.main(MyApp.java:23) |
针对这种问题,Jackson已经预设了配置项: ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER。
在Jackson早期的版本中,可以这样配置:
1 2 3 4 |
ObjectMapper mapper = new ObjectMapper(); mapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true); Map map = mapper.readValue(json, Map.class); |
但是在最近的版本中,这个配置项被移到了JsonReadFeature
类中。对此我是很惆怅的:因为没办法简简单单直接使用configure
方法进行配置了。
Em,在最近的Jackson的版本中需要这样配置:
1 2 3 4 5 |
JsonFactory f = JsonFactory.builder().enable(... feature).build(); // or JsonMapper m = JsonMapper.builder().enable(... feature).build(); // or, since `ObjectMapper` is base type, you can just use that ObjectMapper m = JsonMapper.builder().enable(... feature).build(); |
如果已经有一个ObjectMapper
实例了,还可以考虑创建一个ObjectReader
实例读取数据:
1 2 3 |
ObjectMapper mapper = new ObjectMapper(); ObjectReader reader = mapper.readerFor(Map.class).withFeatures(ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER); |
大体上就是这样了。
参考文档
End!
项目中使用了fastjson,有什么办法处理同样的情况吗?
没有用过
有两年不用RTA了