I am trying to use the Jackson json parser (v2.5.2) to parse a custom json document that is not true json, and I cannot figure out how to make it work. I have a json document that might look like this:
{ "test": { "one":"oneThing", "two": nonStandardThing(), "three": true } }
I want to use ObjectMapper to map this to java.util.Map , and I would like nonStandardThing() added as a String value on my map for key two .
When I run this through ObjectMapper.readValue(json, Map.class) , I get an exception:
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'nonStandardThing': was expecting 'null', 'true', 'false' or NaN at [Source: { "test":{"test1":nonStandardThing(),"test2":"two"}}; line: 1, column: 35] at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1487) at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277)
I tried registering DeserializationProblemHandler using ObjectMapper , but it is never called when this problem occurs.
Here is an example application that shows what I tried:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; public class JacksonDeserializerTest { private Logger log = Logger.getLogger(JacksonDeserializerTest.class.getName()); public JacksonDeserializerTest() { String validJson = "{ \"test\":{\"test1\":\"one\",\"test2\":\"two\"}}"; String invalidJson = "{ \"test\":{\"test1\":nonStandardThing(),\"test2\":\"two\"}}"; ObjectMapper mapper = new ObjectMapper(); mapper.addHandler(new DeserializationProblemHandler() { @Override public boolean handleUnknownProperty(DeserializationContext dc, JsonParser jp, JsonDeserializer<?> jd, Object bean, String property) throws IOException, JsonProcessingException { System.out.println("Handling unknown property: " + property); return false; } }); try { log.log(Level.INFO, "Valid json looks like: {0}", mapper.readValue( validJson, Map.class).toString()); log.log(Level.INFO, "Invalid json looks like: {0}", mapper.readValue(invalidJson, Map.class).toString()); } catch (IOException ex) { log.log(Level.SEVERE, "Error parsing json", ex); } } public static void main(String[] args) { JacksonDeserializerTest test = new JacksonDeserializerTest(); } }
The result is as follows:
Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.jackson.JacksonDeserializerTest <init> INFO: Valid json looks like: {test={test1=one, test2=two}} Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.jackson.JacksonDeserializerTest <init> SEVERE: Error parsing json com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'nonStandardThing': was expecting 'null', 'true', 'false' or NaN at [Source: { "test":{"test1":nonStandardThing(),"test2":"two"}}; line: 1, column: 35] at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1487) at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277) at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken(ReaderBasedJsonParser.java:2129)
Can anyone point out why Handler is never called? Or, if there is a better analysis of this custom json document (jackson or not ...), let me know.