views:

376

answers:

2

Hi, I am using Jackson library's ObjectMapper for deserializing JSON into JAVA objects. I am using Spring 'wiring'. I have created custom deserializers to do the conversion from JSON string to POJO. However, when the input is bad (eg. a number is passed as "124A" - illegal character) a default deserialiser is invoked and bombs with the NumberFormatException. Is there a way to prevent default converters from being called?

A: 

This is the Stacktrace: I am passing $100 instead of 100.

Caused by: org.codehaus.jackson.JsonParseException: Unexpected character ('$' (code 36)): expected a valid value (number, String, array, object, 'true', 'false' or 'null') at [Source: org.mortbay.jetty.HttpParser$Input@470edb99; line: 2, column: 16] at org.codehaus.jackson.JsonParser._constructError(JsonParser.java:943) at org.codehaus.jackson.impl.JsonParserBase._reportError(JsonParserBase.java:632) at org.codehaus.jackson.impl.JsonParserBase._reportUnexpectedChar(JsonParserBase.java:565) at org.codehaus.jackson.impl.Utf8StreamParser._handleUnexpectedValue(Utf8StreamParser.java:1077) at org.codehaus.jackson.impl.Utf8StreamParser.nextToken(Utf8StreamParser.java:212) at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:285) at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:1568) at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:788) at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:398)

vinny
+1  A: 

Ok, given that input is not valid JSON (numbers can not start with or contain '$'), deserializer will not be called, and any change would have to apply to parser. There are no switches in Jackson to allow such content to be considered numbers.

If you can control input, just change value to a String (add double-quotes around value). Parser then passes it as JSON String, and data binding components get a chance to handle it (JsonDeserializer).

StaxMan
I pass the amount as a string and use custom deserializer to convert to number. works flawlessly!
vinny
Perfect, glad it worked out.
StaxMan
Well it turns out, I cannot pass amount as a string for whatever reasons, is there a way to catch these exceptions within the application? (Im using Jetty to run my server)
vinny
You can catch the exception, but not sure if that helps a lot -- parser probably won't read the whole thing. But why is number printed in invalid (non-JSON) format in the first place? Isn't that something that could be fixed.
StaxMan
Ideally it should not be in invalid format. But, just as a general safeguard for that matter, I thought it would be nice to catch all invalid json requests.
vinny
There is a point at which parser has to give up, no matter what. One thing that you could do, if you want to validate, is to use streaming parser (JsonParser), keep on iterating, to know exactly what failed (you will have property name available).
StaxMan