Jackson: Unrecognized field, not marked as ignorable — как исправить ошибку?
Причина ошибки
Jackson по умолчанию строг к структуре JSON. Если в JSON есть поле, которое не соответствует ни одному полю в вашем Java-классе (и отсутствует соответствующий сеттер), библиотека выбрасывает UnrecognizedPropertyException. Это защитный механизм, предотвращающий случайную потерю данных.
Решение #1: Игнорировать неизвестные поля глобально
Самый простой способ — настроить ObjectMapper на игнорирование всех неизвестных полей:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
User user = mapper.readValue(json, User.class);
// age будет проигнорирован
Плюсы: быстрое решение для всего проекта.
Минусы: может скрыть опечатки в именах полей. Используйте осторожно.
Решение #2: Аннотация @JsonIgnoreProperties на классе
Если нужно игнорировать неизвестные поля только для конкретного класса:
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private String name;
private String email;
// геттеры и сеттеры
}
Теперь Jackson будет пропускать все поля, не описанные в классе.
Решение #3: Использовать аннотацию @JsonProperty для строгого маппинга
Если вы хотите контролировать, какие именно поля из JSON должны маппиться, используйте @JsonProperty. Поля без этой аннотации будут игнорироваться:
public class User {
@JsonProperty("name")
private String name;
@JsonProperty("email")
private String email;
// геттеры и сеттеры
}
Решение #4: Создать класс с дополнительными полями (продвинутый вариант)
Если вам нужно сохранить неизвестные поля для дальнейшей обработки, можно использовать @JsonAnySetter:
public class User {
private String name;
private String email;
private Map<String, Object> unknownFields = new HashMap<>();
@JsonAnySetter
public void setUnknownField(String key, Object value) {
unknownFields.put(key, value);
}
// геттеры для name, email и unknownFields
}
Так все "лишние" поля JSON попадут в Map, и вы сможете работать с ними динамически.
Рекомендация для начинающих
- Для разработки и тестов используйте
FAIL_ON_UNKNOWN_PROPERTIES = false— это гибко. - Для продакшена лучше добавлять
@JsonIgnoreProperties(ignoreUnknown = true)на каждый класс, где это необходимо. Так код остаётся явным и понятным. - Всегда проверяйте, не опечатались ли вы в имени поля в JSON или в классе. Ошибка может быть не в "лишнем" поле, а в пропущенном.
Помните: Jackson — мощный инструмент, но требует явной настройки. Правильное управление неизвестными полями сэкономит часы отладки!
<<Альтернативный подход: Использование DTO с проверкой через аннотации
Если вы не хотите слепо игнорировать поля, а предпочитаете явно указать, какие поля допустимы, можно комбинировать @JsonIgnoreProperties с перечислением разрешённых полей:
@JsonIgnoreProperties(ignoreUnknown = true, value = {"age", "phone"})
public class User {
private String name;
private String email;
// геттеры и сеттеры
}
Здесь мы разрешаем игнорировать только age и phone, а любое другое неизвестное поле всё равно вызовет ошибку. Это полезно, когда вы знаете, какие поля могут появляться, но не хотите их обрабатывать.
Ещё один вариант: Использование MixIn
Если вы не можете изменять исходный класс (например, он из сторонней библиотеки), используйте MixIn:
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class UserMixIn {}
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(User.class, UserMixIn.class);
User user = mapper.readValue(json, User.class);
Этот подход позволяет настроить игнорирование полей без изменения кода класса.
Когда какой метод выбрать?
- Глобальная настройка — для быстрых прототипов.
- Аннотация на классе — для чистого кода в продакшене.
- MixIn — когда класс нельзя трогать.
- @JsonAnySetter — когда нужно сохранить неизвестные данные.
Выберите то, что лучше подходит под вашу архитектуру!