Как правильно обрабатывать Jackson InvalidFormatException?
В настоящее время я борюсь с десериализацией Java JSON с Джексоном следующим образом:
Я хочу обработать и десериализовать ответ JSON. Я возвращаюсь из веб-службы и конвертирую ответ в POJO с помощью Jackson. Это работает отлично в большинстве случаев, пока ответ, который я получаю, содержит атрибуты JSON в правильном формате.
Однако, поскольку веб-служба и данные , полученные вами, не поддаются контролю, я не могу полагаться на данные, всегда находящиеся в правильном формате.
Позволь мне привести пример:
В моем POJO есть поле java.util.Date
, а ответ JSON содержит свойство, содержащее строку datetime. Джексон попытается разобрать строку и преобразовать ее в Date
. Если формат даты матчей в ObjectMapper's
DateFormat (ObjectMapper.setDateFormat(...)
), все в порядке. Если формат отличается, я получаю InvalidFormatException
.
Проблема в том, что датаформат, отправленный из службы, может отличаться. Я могу получить даты, отформатированные как 2014-11-02T00:00:00Z
, но я также могу получить даты, отформатированные как 2014-11
(идентификация всего одного месяца вместо целого дня и времени).
Я знаю, я могу написать собственный десериализатор, который мог бы позаботиться об этом конкретном случае и правильно обработать даты с разными форматами дат. Но поскольку это только устранит проблемы с Dates
, но не с потенциальными другими типами данных, я ищу более общий подход. (Что произойдет, например, если я ожидаю Double и получите буквенно-цифровую строку?)
Я хотел бы иметь возможность игнорировать все случаи, в которых происходит InvalidFormatException
, и определять значение по умолчанию (например, null
) в соответствующее поле POJO.
И это было бы очень полезно для меня, если, несмотря на возвращение недействительного dateformat или любое другое InvalidFormatException
, остальная часть JSON все равно будет десериализована в POJO.
Это возможно с Джексоном?
Спасибо, что прочитали мой вопрос до конца, и я был бы благодарен за любые указатели в правильном направлении.
Ответы
Ответ 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;
}
});