As I tried to deserialize a json string from database with jackson, I received error message like this:
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) |
The json string is:
1 |
{"text":"Hello \World!"} |
It’s the Backslash in the source json string which lead to the error.
To fix the error, we can take advantage of the config item: ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.
In the earier versions of jackson, we can config like this:
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); |
But in the lastest version(2.11.0), I found the config was moved into the class JsonReadFeature
. Em , we need to change the config like this :
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(); |
If there is already an instance of ObjectMapper
, we can create an instance of ObjectReader
to execute the work:
1 2 |
ObjectReader r = mapper.readerFor(MyType.class).with(... feature...); MyType value = r.readValue(source); |
All!