Spring 中引入 Jackson 3 支援

工程 | Sébastien Deleuze | 2025年10月7日 | ...

這是“通往GA之路”系列中的一篇新博文,就在Jackson 3.0.0 GA釋出幾天後,此篇博文分享了更多關於Jackson 3新支援的細節,該支援即將引入到Spring Boot 4及相關的Spring專案組合中。

Jackson是目前JVM上最常用的JSON庫,Spring中引入Jackson 3的支援是我們提供額外增強的機會,這是我在10多年前宣佈的廣受歡迎的Spring中Jackson整合改進的後續!

Spring和Jackson團隊之間的緊密合作

當 Spring 團隊致力於利用流行開源庫的新版本時,雖然可能不明顯,但部分工作有時是與維護者合作進行改進,這將有益於更廣泛的社群。

Jackson 3 就是一個很好的例子,我要感謝 Tatu Saloranta(Jackson 專案負責人)在釋出候選階段願意聽取我們的反饋——這使得以下改進成為可能:

Spring Boot 4.0 中 Jackson 支援的現狀

一般原則是,自 Spring Boot 4.0 和 Spring Framework 7.0 起,Spring 產品組合將:

  • 引入 Jackson 3 支援
  • 棄用 Jackson 2 支援,並最終移除
  • 將預設 Jackson 版本(類路徑檢測、依賴項)切換到 Jackson 3

主要例外是 Spring AI,它打算在 2026 年上半年釋出的 2.0 版本中引入 Jackson 3 支援。

更具體地說,Spring Boot 4.0 將:

  • 為 Jackson 2 和 3 提供依賴管理
  • 執行 Jackson 3 的自動配置
  • 棄用 Jackson 2 的自動配置,並最終移除
  • 在其 spring-boot-starter-jsonspring-boot-starter-jackson 啟動器依賴項中使用 Jackson 3

升級到 Spring Boot 4.0 時,建議的順序是:

  1. 遷移到 Jackson 3
  2. 遷移到 Jackson 3 並設定 spring.jackson.use-jackson2-defaults
  3. 暫時使用 Jackson 2,以方便遷移到 Spring Boot 4.0,作為向 Jackson 3 過渡的墊腳石

仍依賴 Jackson 2 的傳遞依賴項仍受支援,並將受益於 Jackson 2 依賴管理。

遷移到 Jackson 3

本節重點介紹典型 Spring Boot 應用程式最重要的遷移步驟,有關其他方面的更多詳細資訊,請參閱 Jackson 3 遷移指南。相關的 Open Rewrite 配方 可以幫助自動化其中一些更改,而 Spring Application Advisor 將為您的 Spring Boot 應用程式的增量遷移提供最全面的選項。

更新包

升級時遇到的第一個破壞性更改可能是 Jackson 包(和依賴項 groupID)從 com.fasterxml.jackson 更改為 tools.jackson除了 jackson-annotations,它出於向後相容性原因保持不變

適應新的預設設定

Jackson 3 更改了一些預設設定,與 Jackson 2 相比,因此您應該相應地調整測試(如果可以,建議這樣做),或者自定義 Jackson 3 配置以恢復一些以前的預設設定。

最可能破壞測試的更改如下:

  • 如果您在測試中將 Jackson 序列化與原始字串進行比較,則很可能會受到 MapperFeature.SORT_PROPERTIES_ALPHABETICALLY 現在設定為 true 的影響。
  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 現在稱為 DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS 已更改為 false,以將日期序列化為 ISO-8601 字串。

如果您至少最初希望儘可能使用與 Jackson 2 相似的預設設定,則可以使用 spring.jackson.use-jackson2-defaults 屬性。當設定為 true 時,自動配置的 JsonMapper 將具有與 Spring Boot 3 中 Jackson 2 預設設定儘可能一致的預設設定。

Jackson 模組

一些以前的 Jackson 2 模組現在已內置於 Jackson 3 中,例如 parameter-names 或 datatype-jsr310。以前透過 Jackson2ObjectMapperBuilder 啟用的其他模組現在透過 JDK 服務載入器設施自動發現,用於 Spring Framework 提供的轉換器和編解碼器。

當然,也可以透過 JsonMapper.Builder 配置自定義模組。

從 ObjectMapper 到 JsonMapper

Jackson 3 引入了許多更改和增強功能,但從 Spring 的角度來看,最重要的一項是從 Jackson 2 中可變的 ObjectMapper 切換到 Jackson 3 中不可變的 JsonMapper

JsonMapper 擴充套件了 ObjectMapper,專門用於 JSON 格式,遵循與其他格式(XmlMapperYAMLMapperSmileMapper 等)類似的模式,並且 Spring 支援已更新為使用此特定於格式的變體,遵循 Jackson 3 最佳實踐。

此外,由於 Jackson 和 Spring 的預設設定大部分一致,並且引入了第一類 JsonMapper.BuilderSpring Framework 不再提供 Jackson2ObjectMapperBuilder 的等效項,您應該只使用 Jackson 構建器

例如,對於 Spring Boot 3 及其 Jackson 2 支援,spring.jackson.serialization.indent-output=true 的程式設計等效項是

@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 擴充套件了 GenericHttpMessageConverter,後者無法正確傳遞額外的序列化資訊,例如序列化檢視或 FilterProvider,因此需要 MappingJacksonValue 包裝器。

例如,假設我們使用 @JsonView(Summary.class) 註解 User 記錄,以標識要序列化或反序列化的元件子集

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 包裝器來指定應使用 Summary JSON 檢視。

var user = new User("Marcel", "Martin", LocalDate.of(1971, 7, 12),
    "[email protected]", "1234 rue Gambetta", 69002, "Lyon", "France");
var jacksonValue = new MappingJacksonValue(user);
jacksonValue.setSerializationView(Summary.class);
var response = this.restTemplate.postForObject("https://:8080/create", jacksonValue, String.class);

這允許僅序列化用 @JsonView(Summary.class) 註解的記錄元件

{
  "firstname" : "Marcel",
  "lastname" : "Martin",
  "email" : "[email protected]"
}

從 Spring Framework 7 開始,您可以利用基於 Jackson 3 的新 JacksonJsonHttpMessageConverter 實現了 SmartHttpMessageConverter,它支援序列化提示,因此您可以這樣編寫

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

不再有可變包裝器,只有可選的提示。

暫時繼續使用 Jackson 2 支援

建議遷移到 Spring Boot 4 的應用程式遷移到 Jackson 3,但如果需要,可以繼續使用 Jackson 2,甚至同時使用 Jackson 2 和 3。請注意,這可能需要額外的依賴項和配置改進。

如果您想暫時繼續使用 Jackson 2 支援而不是 Jackson 3,您可以例如:

  • 排除 spring-boot-jackson 的直接或傳遞依賴項(例如,來自 spring-boot-starter-jacksonspring-boot-starter-json),並改用 spring-boot-jackson2
  • 對於配置屬性,使用 spring.jackson2 而不是 spring.jackson

Jackson 2 自動配置以棄用形式保留了一段時間,僅用於幫助逐步遷移到 Jackson 3。

Spring Security Jackson 3 支援

Spring Security 7.0 引入了Jackson 3 支援,並棄用了 Jackson 2 支援。

它還透過利用 PolymorphicTypeValidator 使 Jackson 支援更安全,其中預設只允許 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 支援使用與現在已棄用的 Jackson 2 相容的格式,因此使用 Jackson 2 序列化的類例項應該可以使用 Jackson 3 支援進行反序列化。

Spring Data Jackson 3 支援

Spring Data 4.0 及其核心模組完全支援 Jackson 3。建議遷移到 Spring Data 4 的應用程式遷移到 Jackson 3,但如果需要,可以繼續使用 Jackson 2,甚至同時使用 Jackson 2 和 3。請注意,Jackson 3 附帶了一組不同的預設設定,這可能需要遷移您的持久資料或更新 Jackson 3 預設設定以匹配 Jackson 2 設定。

由於 Spring Data 包含大量專案,讓我們單獨探討每個模組:

Spring Data Commons

Spring Data Commons 添加了對 Jackson 3 的支援,如果類路徑中只有 Jackson 2,則會回退到 Jackson 2。這主要適用於透過 ProjectingJacksonHttpMessageConverterSpringDataWebConfiguration 的 Web 支援。

JacksonResourceReaderJacksonRepositoryPopulatorFactoryBeanJackson2ResourceReaderJackson2RepositoryPopulatorFactoryBean 的基於 Jackson 3 的變體。

如果您使用 Jackson 2 以及 Spring Data 的 XML 名稱空間支援 (<repository:jackson2-populator …>),並且您想遷移到 Jackson 3,那麼您將必須在 Java 配置中定義一個 JacksonRepositoryPopulatorFactoryBean bean。

如果您碰巧使用 SpringDataJacksonModules,那麼您需要考慮遷移到 SpringDataJackson3Modules,以實現基於 Jackson 3 的模組安排。

Spring Data Redis

Spring Data Redis 4.0 附帶了用於 Jackson 3 的 JacksonHashMapperJacksonJsonRedisSerializerGenericJacksonJsonRedisSerializer 實現。在使用 JacksonObjectReaderJacksonObjectWriter 時,請確保使用 Jackson2ObjectReaderJackson2ObjectWriter 對您的實現進行改造,因為類命名已對齊以實現一致的方案。

Spring Data REST

Spring Data REST 本質上是一個圍繞 Jackson 的大型包裝器,不支援使用 Jackson 2 的操作模式。如果您想使用新的 Spring Data REST 版本,則您的應用程式必須遷移到 Jackson 3。Spring HATEOAS 也是如此,因為這兩個框架都大量使用 Jackson。

Spring Data Couchbase、Elasticsearch、驅動程式

更大的生態系統正在緩慢追趕 Jackson 3。Couchbase、Elasticsearch 和一些驅動程式內部使用 Jackson 2,並將繼續這樣做。在大多數情況下,這些元件中的 Jackson 用法與您的實體無關,因為它是它們作為 JSON 解析器和寫入器的機制。

結論

Jackson 3 在安全性、API、預設配置和功能方面帶來了巨大的好處,但它也帶來了需要一些遷移工作的破壞性更改,Spring 團隊完全意識到這一點,並投入了大量精力提供最佳的安排和相關指導,併為以前的版本提供行業領先的擴充套件支援,以便您有時間進行升級。

一如既往,我們期待您的反饋,並將盡最大努力改進我們的指導、文件並回答您的相關問題。

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有