Команда Spring официально представила поддержку Jackson 3 — одного из крупнейших обновлений в экосистеме JSON для JVM. Уже начиная с Spring Boot 4 и Spring Framework 7, Jackson 3 становится версией по умолчанию, а Jackson 2 помечается как deprecated. В новом переводе от команды Spring АйО поговорим про нововведения — улучшенную безопасность, переход к JsonMapper, отказ от MappingJacksonValue, поддержку новых API и настройку через builder-интерфейсы.


Представляем поддержку Jackson 3 в Spring

Поддержка будет реализована в Spring Boot 4 и других проектах Spring-портфолио.

Jackson остаётся самой популярной библиотекой для работы с JSON в экосистеме JVM, и внедрение поддержки Jackson 3 в Spring — отличная возможность для нас предложить дополнительные улучшения в продолжение интеграции с Jackson, о которой я впервые рассказал более десяти лет назад!

Тесное сотрудничество между командами Spring и Jackson

Когда команда Spring работает над поддержкой новых версий популярных open source-библиотек, за кулисами часто ведётся значительная работа по взаимодействию с мейнтейнерами, чтобы внести улучшения, полезные для всего сообщества.

Jackson 3 — отличный пример такого взаимодействия. Я хочу поблагодарить Тату Саларанту (руководителя проекта Jackson) за готовность учитывать наш фидбэк в фазе релиз-кандидатов, благодаря чему удалось реализовать следующие улучшения:

Статус поддержки Jackson в Spring Boot 4

Начиная с Spring Boot 4 и Spring Framework 7, Spring-портфолио:

  • внедряет поддержку Jackson 3,

  • помечает поддержку Jackson 2 как deprecated с целью последующего удаления,

  • переключает версию Jackson, активируемую по умолчанию (определяемую через classpath), на Jackson 3.

Основное исключение — Spring AI, где поддержка Jackson 3 появится в версии 2.0 в первой половине 2026 года.

Более конкретно, Spring Boot 4:

  • обеспечивает управление зависимостями как для Jackson 2, так и для Jackson 3,

  • выполняет автонастройку только для Jackson 3,

  • использует Jackson 3 в зависимостях spring-boot-starter-json и spring-boot-starter-jackson.

Приложениям, мигрирующим на Spring Boot 4, рекомендуется переходить на Jackson 3, хотя использование Jackson 2 по-прежнему возможно (см. соответствующий раздел ниже). Транзитивные зависимости, использующие Jackson 2, по-прежнему поддерживаются и получают управление зависимостями Jackson 2.

Миграция на Jackson 3

Этот раздел посвящён ключевым шагам по миграции типичных приложений Spring Boot. Подробности доступны в руководстве по миграции на Jackson 3. Также помогут автоматизировать процесс Open Rewrite, а Spring Application Advisor обеспечит наиболее полный путь к пошаговой миграции.

Обновление пакетов

Первое несовместимое изменение, с которым вы столкнётесь при обновлении, — это изменение пакета и groupID зависимостей: теперь com.fasterxml.jackson заменён на tools.jackson, за исключением jackson-annotations, который сохранён для обратной совместимости.

Адаптация к новым настройкам по умолчанию

Jackson 3 изменил некоторые значения по умолчанию по сравнению с Jackson 2. Вы должны либо адаптировать свои тесты (рекомендуется), либо настроить Jackson 3, чтобы восстановить прежние значения.

Изменения, которые скорее всего повлияют на ваши тесты:

  • Если вы сравниваете сериализацию с помощью Jackson с необработанными строками в ваших тестах, на вас, вероятно, повлияет то, что MapperFeature.SORT_PROPERTIES_ALPHABETICALLY теперь включён по умолчанию.

  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, теперь переименованный в DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS, установлен в значение false, т.е. даты сериализуются в формате ISO-8601.

Если вы хотите на начальном этапе сохранить настройки, максимально близкие к Jackson 2, используйте следующее:

@Bean
JsonMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> builder.configureForJackson2();
}

Модули Jackson

Некоторые модули Jackson 2 теперь включены в состав Jackson 3, например parameter-names и datatype-jsr310. Другие модули, которые ранее подключались через Jackson2ObjectMapperBuilder, теперь обнаруживаются автоматически с помощью механизма service loader в JDK — применительно к конвертерам и кодекам, предоставляемым Spring Framework.

Также возможно вручную настроить пользовательские модули через JsonMapper.Builder.

Переход от ObjectMapper к JsonMapper

Jackson 3 содержит множество изменений, но с точки зрения Spring наиболее важное — это переход от mutable ObjectMapper (Jackson 2) к immutable JsonMapper (Jackson 3).

JsonMapper — это расширение ObjectMapper, специфичное для формата JSON (по аналогии с XmlMapper, YAMLMapper, SmileMapper и др.). Поддержка в Spring была обновлена с учётом best practices Jackson 3 и теперь использует именно этот формат-ориентированный вариант.

Кроме того, поскольку настройки Jackson и Spring теперь в основном согласованы, а также с появлением полноценного JsonMapper.Builder, Spring Framework больше не предоставляет эквивалента Jackson2ObjectMapperBuilder. Вместо этого следует использовать стандартный Jackson-билдер.

Пример из Spring Boot 3 с поддержкой Jackson 2:

@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> builder.indentOutput(true);
}

Аналогичный пример в Spring Boot 4 с поддержкой Jackson 3:

@Bean
JsonMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> builder.enable(SerializationFeature.INDENT_OUTPUT);
}

Прощай, MappingJacksonValue

MappingJackson2HttpMessageConverter, являющийся deprecated на данный момент,  расширял GenericHttpMessageConverter, который не позволяет корректно передавать дополнительную информацию для сериализации, такую как представление сериализации (serialization view) или FilterProvider, — отсюда и необходимость использовать обёртку MappingJacksonValue.

Предположим, вы аннотировали record-класс User с помощью @JsonView(Summary.class), чтобы указать подмножество компонентов, которые нужно сериализовать или десериализовать:

public record User(
    @JsonView(Summary.class) String firstname,
    @JsonView(Summary.class) String lastname,
    LocalDate birthdate,
    @JsonView(Summary.class) String email,
    String address,
    int postalCode,
    String city,
    String country) {
}

Начиная с Spring Framework 6 и ранее, на клиентской стороне нужно было использовать обёртку MappingJacksonValue, чтобы указать, что нужно использовать JSON-представление Summary:

var user = new User("Marcel", "Martin", LocalDate.of(1971, 7, 12),
    "m@m.fr", "1234 rue Gambetta", 69002, "Lyon", "France");
var jacksonValue = new MappingJacksonValue(user);
jacksonValue.setSerializationView(Summary.class);
var response = this.restTemplate.postForObject("http://localhost:8080/create", jacksonValue, String.class);

Результатом будет сериализация только тех компонентов record-класса, которые аннотированы @JsonView(Summary.class):

{
  "firstname" : "Marcel",
  "lastname" : "Martin",
  "email" : "m@m.fr"
}

Начиная с Spring Framework 7, можно воспользоваться тем, что новый JacksonJsonHttpMessageConverter, основанный на Jackson 3, реализует SmartHttpMessageConverter, который поддерживает подсказки для сериализации (serialization hints). Теперь это можно написать так:

var user = new User("Marcel", "Martin", LocalDate.of(1971, 7, 12),
    "m@m.fr", "1234 rue Gambetta", 69002, "Lyon", "France");
var response = this.restClient.post().uri("http://localhost:8080/create")
    .hint(JsonView.class.getName(), Summary.class).body(user)
    .retrieve().body(String.class);

Больше не нужно использовать mutable обёртки — только опциональные хинты.

Временное продолжение использования Jackson 2

Приложениям, мигрирующим на Spring Boot 4, рекомендуется переходить на Jackson 3, однако при необходимости они могут временно продолжать использовать Jackson 2 — или даже одновременно использовать обе версии. Следует учитывать, что для этого может потребоваться явное добавление зависимостей Jackson 2 и некоторая ручная настройка.

В связке Spring Boot 4 и Spring MVC, если вы исключите зависимости Jackson 3 и добавите зависимости Jackson 2, то поддержка Jackson 2 будет использоваться по умолчанию, так как она будет обнаружена через WebMvcConfigurationSupport.

Если же в classpath присутствуют одновременно и Jackson 2, и Jackson 3, Spring Framework предоставляет новый тип org.springframework.http.converter.HttpMessageConverters и соответствующий кастомайзер Spring Boot 4, который позволяет явно задать использование Jackson 2:

@Bean
@SuppressWarnings("removal")
public ServerHttpMessageConvertersCustomizer jackson2ServerConvertersCustomizer() {
    return builder -> builder.jsonMessageConverter(new MappingJackson2HttpMessageConverter());
}

Поддержка Jackson 3 в Spring Security

Соответствующий pull request пока не смёржен и может быть доработан, однако уже сейчас стоит отметить, что, помимо внедрения поддержки Jackson 3 и перевода Jackson 2 с статус deprecated, в Spring Security 7.0 планируется сделать поддержку Jackson 3 более безопасной за счёт отключения глобального default typing (подробности — в этом блоге).

Вместо этого будет использоваться PolymorphicTypeValidator, который по умолчанию разрешает только типы Spring Security, при этом приложение сможет добавлять свои собственные типы. Например:

ClassLoader loader = getClass().getClassLoader();
BasicPolymorphicTypeValidator.Builder typeValidatorBuilder = BasicPolymorphicTypeValidator.builder()
    .allowIfSubType(CustomGrantedAuthority.class);
JsonMapper mapper = JsonMapper.builder()
    .addModules(SecurityJacksonModules.getModules(loader, typeValidatorBuilder))
    .build();

Из-за изменений в Jackson 3 и отключения глобального default typing, формат сериализованных данных в Jackson 2 и Jackson 3 будет отличаться. Однако, чтобы упростить миграцию приложений, которые, например, хранят сериализованные данные Jackson 2 в базах данных, будет предоставлен режим совместимости с Jackson 2. Это позволит мигрировать на Spring Boot 4 и Spring Security 7, продолжая использовать прежний формат данных Jackson 2 с помощью Jackson 3.

Поддержка Jackson 3 в Spring Data

Spring Data 4.0 поставляется с полной поддержкой Jackson 3 для своих основных модулей. Приложениям, переходящим на Spring Data 4, рекомендуется использовать Jackson 3, однако при необходимости можно продолжить работу с Jackson 2 или даже использовать обе версии одновременно. При этом важно учитывать, что Jackson 3 использует иной набор настроек по умолчанию, что может потребовать либо миграции существующих данных, либо настройки Jackson 3 для соответствия прежним значениям.

Поскольку Spring Data включает в себя целый ряд проектов, давайте рассмотрим изменения по модулям отдельно.

Spring Data Commons

В Spring Data Commons добавлена поддержка Jackson 3 с возможностью отката к Jackson 2, если в classpath присутствует только Jackson 2. Это касается в основном поддержки Web через ProjectingJacksonHttpMessageConverter и SpringDataWebConfiguration.

Появились новые реализации JacksonResourceReader и JacksonRepositoryPopulatorFactoryBean, основанные на Jackson 3, заменяющие соответствующие версии на Jackson 2: Jackson2ResourceReader и Jackson2RepositoryPopulatorFactoryBean.

Если вы используете поддержку XML-пространств имён Spring Data вместе с Jackson 2 (<repository:jackson2-populator …>) и хотите перейти на Jackson 3, необходимо вручную объявить bean JacksonRepositoryPopulatorFactoryBean в Java-конфигурации.

Также, если вы используете SpringDataJacksonModules, рекомендуется перейти на SpringDataJackson3Modules для корректной работы с Jackson 3.

Spring Data Redis

Spring Data Redis 4.0 включает реализации JacksonHashMapper, JacksonJsonRedisSerializer и GenericJacksonJsonRedisSerializer для Jackson 3.

При использовании JacksonObjectReader и JacksonObjectWriter убедитесь, что вы адаптировали реализацию, используя Jackson2ObjectReader и Jackson2ObjectWriter, так как схема именования классов была изменена для единообразия.

Spring Data REST

Spring Data REST является, по сути, крупной обёрткой вокруг Jackson и не поддерживает работу с Jackson 2. Если вы планируете использовать новую версию Spring Data REST, то ваше приложение обязательно должно перейти на Jackson 3.

Аналогичное требование распространяется и на Spring HATEOAS, так как оба фреймворка активно используют Jackson.

Spring Data Couchbase, Elasticsearch, драйверы

Остальные частиэкосистемы Spring Data постепенно переходят на Jackson 3. В частности, Couchbase, Elasticsearch и некоторые драйверы по-прежнему используют Jackson 2 во внутренней реализации и продолжат это делать.

В большинстве случаев использование Jackson в этих компонентах не связано напрямую с вашими сущностями, так как Jackson используется исключительно как механизм парсинга и записи JSON.

Заключение

Jackson 3 приносит серьёзные улучшения в плане безопасности, API, конфигураций по умолчанию и новых возможностей. Однако он также вносит изменения, нарушающие обратную совместимость, что потребует определённой работы по миграции.

Команда Spring осознаёт это и приложила значительные усилия для создания наилучшей архитектуры перехода, подробной документации и рекомендаций, а также предлагает расширенную поддержку предыдущей версии, чтобы дать вам время для полноценной миграции.


Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.