Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle Jackson InvalidFormatException gracefully?

Tags:

java

json

jackson

I'm currently struggling with Java JSON deserialization with Jackson in the following way:

I want to process and deserialize a JSON response I get back from a webservice and convert the response into POJOs with the help of Jackson. This works fine most of the time, as long as the response I'm getting contains JSON attributes in the correct format.

As however the webservice and the delivered data is out of my control, I can not rely on the data always being in the correct format.

Let me give you an example:

In my POJO, there's a java.util.Date field, and the JSON response contains a property holding a datetime string. Jackson will try to parse the string and convert it into a Date. If the date format matches the ObjectMapper's dateformat (ObjectMapper.setDateFormat(...)), everything is fine. If the format is different, I get an InvalidFormatException.

The problem now is, the dateformat sent from the service can differ. I can get dates formatted like 2014-11-02T00:00:00Z, but I can also get dates formatted like 2014-11 (identifying just a single month instead of an entire datetime).

I know, I can write a custom deserializer which could take care of this exact case and handle datestrings with different date formats correctly. But as this would only fix issues with Dates, but not with potential other datatypes, I'm searching for a more general approach. (What happens e.g. if I expect a Double and receive an alphanumerical string?)

What I would like is to have the possibility to ignore all cases in which an InvalidFormatException happens and define a default value (like null) to the respective POJO field.

And it would be really valuable for me, if despite an invalid dateformat being returned or any other InvalidFormatException happening, the rest of the JSON would still be deserialized into the POJO.

Is this in any way possible with Jackson?

Thank you for reading my question till the end and I would be grateful for any pointers in the right direction.

like image 641
Andreas Maly Avatar asked Nov 02 '14 12:11

Andreas Maly


1 Answers

Not sure if this is best practice, I have little experience with Jackson.

You can add a DeserializationProblemHandler to the ObjectMapper to specify what happens when the deserializer encounters a weird String or weird number.

In your case you could set the handler such that when encountering an unrecognized format, instead of throwing an InvalidFormatException, it just returns null:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addHandler(new DeserializationProblemHandler() {
    @Override
    public Object handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType, String valueToConvert, String failureMsg) throws IOException {
        return null;
    }

    @Override
    public Object handleWeirdNumberValue(DeserializationContext ctxt, Class<?> targetType, Number valueToConvert, String failureMsg) throws IOException {
        return null;
    }
});
like image 77
explv Avatar answered Nov 05 '22 12:11

explv