【问题标题】:How to handle Jackson InvalidFormatException gracefully?如何优雅地处理 Jackson InvalidFormatException?
【发布时间】:2014-11-02 12:20:37
【问题描述】:

我目前正在通过以下方式与 Jackson 进行 Java JSON 反序列化:

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

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

让我举个例子:

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

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

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

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

如果尽管返回了无效的日期格式或发生任何其他 InvalidFormatException,这对我来说真的很有价值,JSON 的其余部分仍然被反序列化进入 POJO。

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

感谢您阅读我的问题直到最后,如果您有任何正确方向的指示,我将不胜感激。

【问题讨论】:

  • 我也想知道最佳实践。

标签: java json jackson


【解决方案1】:

不确定这是否是最佳做法,我对 Jackson 的经验很少。

您可以将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;
    }
});

【讨论】:

  • 我能以某种方式检索整个对象吗?在他们那一刻,我只收到字段的名称、值及其位置。为了更好地确定它,最好记录整个对象。
  • 'throws IOException' 在那里是多余的
猜你喜欢
  • 2011-11-26
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 2014-07-10
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多