21

Jackson处理json中的反斜杠

 3 years ago
source link: http://www.zhyea.com/2020/10/22/how-to-deal-with-backslash-with-jackson.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在使用jackson处理json时遇到了反斜杠相关的问题。比如我们从数据库或文件中读到了这样的一个json字符串:

{"text":"Hello \World!"}

可以看到在 World 前面有一个反斜杠。因为这个反斜杠,JetBrains IDEA会提示这是一个错误的字符串,使用jakcson处理这个json字符串时也会报错,错误信息如下:

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早期的版本中,可以这样配置:

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的版本中需要这样配置:

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 实例读取数据:

ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = 
        mapper.readerFor(Map.class).withFeatures(ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);

大体上就是这样了。

参考文档

How to use JsonReadFeature

End!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK