如何优雅地处理Jackson InvalidFormatException?

时间:2014-11-02 12:20:38

标签: java json jackson

我目前正在以下列方式与杰克逊进行Java JSON反序列化:

我想处理和反序列化我从Web服务返回的JSON响应,并在Jackson的帮助下将响应转换为POJO。只要我得到的响应包含正确格式的JSON属性,这在大多数情况下都可以正常工作。

然而,由于网络服务和交付的数据不受控制,我无法依赖数据始终采用正确的格式。

让我举个例子:

在我的POJO中,有一个java.util.Date字段,而JSON响应包含一个包含日期时间字符串的属性。杰克逊将尝试解析字符串并将其转换为Date。如果日期格式与ObjectMapper's日期格式(ObjectMapper.setDateFormat(...))匹配,则一切正常。如果格式不同,我会得到InvalidFormatException

现在的问题是,从服务发送的日期格式可能不同。我可以将日期格式化为2014-11-02T00:00:00Z,但我也可以将日期格式化为2014-11(仅标识一个月而不是整个日期时间)。

我知道,我可以编写一个自定义反序列化程序,它可以处理这个确切的情况并正确处理具有不同日期格式的datetring。但由于这只能解决Dates的问题,而不能解决潜在的其他数据类型问题,因此我正在寻找更通用的方法。 (例如,如果我期望Double并接收字母数字字符串会发生什么?)

我希望有可能忽略InvalidFormatException发生的所有情况,并为相应的POJO字段定义默认值(如null)。

这对我来说非常有价值,如果尽管返回了无效的dateformat或发生任何其他InvalidFormatException,那么其余的JSON 仍会被反序列化进入POJO。

这对杰克逊来说有什么可能吗?

感谢您阅读我的问题直到最后,我将非常感谢任何指示正确的方向。

1 个答案:

答案 0 :(得分:1)

不确定这是否是最佳做法,我对杰克逊的经验不多。

您可以向DeserializationProblemHandler添加ObjectMapper,以指定当反序列化程序遇到奇怪的字符串或奇怪数字时会发生什么。

在您的情况下,您可以设置处理程序,以便在遇到无法识别的格式时,而不是抛出InvalidFormatException,它只返回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;
    }
});