From 2d7323bb7f6fcfd7cac71c0c515a657037fd0142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Mon, 7 Jul 2025 18:15:44 +0200 Subject: [PATCH] Update Spring MVC message converters documentation Closes gh-35166 --- framework-docs/framework-docs.gradle | 4 +- .../webmvc/mvc-config/message-converters.adoc | 45 ++----------------- .../WebConfiguration.java | 31 +++++++------ .../WebConfiguration.kt | 30 ++++++++----- .../WebConfiguration.xml | 30 ------------- 5 files changed, 42 insertions(+), 98 deletions(-) delete mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.xml diff --git a/framework-docs/framework-docs.gradle b/framework-docs/framework-docs.gradle index b9b6746d7ba..89250dcf590 100644 --- a/framework-docs/framework-docs.gradle +++ b/framework-docs/framework-docs.gradle @@ -62,8 +62,6 @@ dependencies { implementation(project(":spring-webmvc")) implementation(project(":spring-websocket")) - implementation("com.fasterxml.jackson.core:jackson-databind") - implementation("com.fasterxml.jackson.module:jackson-module-parameter-names") implementation("com.github.ben-manes.caffeine:caffeine") implementation("com.mchange:c3p0:0.9.5.5") implementation("com.oracle.database.jdbc:ojdbc11") @@ -81,4 +79,6 @@ dependencies { implementation("org.eclipse.jetty.websocket:jetty-websocket-jetty-api") implementation("org.jetbrains.kotlin:kotlin-stdlib") implementation("org.junit.jupiter:junit-jupiter-api") + implementation("tools.jackson.core:jackson-databind") + implementation("tools.jackson.dataformat:jackson-dataformat-xml") } diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc index a1e2d63303f..1535f411714 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-config/message-converters.adoc @@ -3,47 +3,10 @@ [.small]#xref:web/webflux/config.adoc#webflux-config-message-codecs[See equivalent in the Reactive stack]# -You can set the `HttpMessageConverter` instances to use in Java configuration, -replacing the ones used by default, by overriding -{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters-java.util.List-[`configureMessageConverters()`]. -You can also customize the list of configured message converters at the end by overriding -{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#extendMessageConverters-java.util.List-[`extendMessageConverters()`]. +You can configure the `HttpMessageConverter` instances to use by overriding +{spring-framework-api}/web/servlet/config/annotation/WebMvcConfigurer.html#configureMessageConverters(org.springframework.http.converter.HttpMessageConverters.Builder)[`configureMessageConverters()`]. -TIP: In a Spring Boot application, the `WebMvcAutoConfiguration` adds any -`HttpMessageConverter` beans it detects, in addition to default converters. Hence, in a -Boot application, prefer to use the {spring-boot-docs-ref}/web/servlet.html#web.servlet.spring-mvc.message-converters[HttpMessageConverters] -mechanism. Or alternatively, use `extendMessageConverters` to modify message converters -at the end. - -The following example adds XML and Jackson JSON converters with a customized `ObjectMapper` -instead of the default ones: +The following example configures custom Jackson JSON and XML converters with customized mappers instead of the default +ones: include-code::./WebConfiguration[tag=snippet,indent=0] - -In the preceding example, -{spring-framework-api}/http/converter/json/Jackson2ObjectMapperBuilder.html[`Jackson2ObjectMapperBuilder`] -is used to create a common configuration for both `MappingJackson2HttpMessageConverter` and -`MappingJackson2XmlHttpMessageConverter` with indentation enabled, a customized date format, -and the registration of -{jackson-github-org}/jackson-module-parameter-names[`jackson-module-parameter-names`], -Which adds support for accessing parameter names (a feature added in Java 8). - -This builder customizes Jackson's default properties as follows: - -* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES[`DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES`] is disabled. -* {jackson-docs}/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/MapperFeature.html#DEFAULT_VIEW_INCLUSION[`MapperFeature.DEFAULT_VIEW_INCLUSION`] is disabled. - -It also automatically registers the following well-known modules if they are detected on the classpath: - -* {jackson-github-org}/jackson-datatype-jsr310[jackson-datatype-jsr310]: Support for Java 8 Date and Time API types. -* {jackson-github-org}/jackson-datatype-jdk8[jackson-datatype-jdk8]: Support for other Java 8 types, such as `Optional`. -* {jackson-github-org}/jackson-module-kotlin[jackson-module-kotlin]: Support for Kotlin classes and data classes. - -NOTE: Enabling indentation with Jackson XML support requires -https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.woodstox%22%20AND%20a%3A%22woodstox-core-asl%22[`woodstox-core-asl`] -dependency in addition to https://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jackson-dataformat-xml%22[`jackson-dataformat-xml`] one. - -Other interesting Jackson modules are available: - -* https://github.com/zalando/jackson-datatype-money[jackson-datatype-money]: Support for `javax.money` types (unofficial module). -* {jackson-github-org}/jackson-datatype-hibernate[jackson-datatype-hibernate]: Support for Hibernate-specific types and properties (including lazy-loading aspects). diff --git a/framework-docs/src/main/java/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.java index 2015631ba32..19f4b52feba 100644 --- a/framework-docs/src/main/java/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.java +++ b/framework-docs/src/main/java/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.java @@ -17,15 +17,15 @@ package org.springframework.docs.web.webmvc.mvcconfig.mvcconfigmessageconverters; import java.text.SimpleDateFormat; -import java.util.List; -import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import tools.jackson.dataformat.xml.XmlMapper; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.json.JsonMapper; import org.springframework.context.annotation.Configuration; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverters; +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; +import org.springframework.http.converter.xml.JacksonXmlHttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @SuppressWarnings("removal") @@ -34,13 +34,18 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; public class WebConfiguration implements WebMvcConfigurer { @Override - public void configureMessageConverters(List> converters) { - Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder() - .indentOutput(true) - .dateFormat(new SimpleDateFormat("yyyy-MM-dd")) - .modulesToInstall(new ParameterNamesModule()); - converters.add(new MappingJackson2HttpMessageConverter(builder.build())); - converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); + public void configureMessageConverters(HttpMessageConverters.Builder builder) { + JsonMapper jsonMapper = JsonMapper.builder() + .findAndAddModules() + .enable(SerializationFeature.INDENT_OUTPUT) + .defaultDateFormat(new SimpleDateFormat("yyyy-MM-dd")) + .build(); + XmlMapper xmlMapper = XmlMapper.builder() + .findAndAddModules() + .defaultUseWrapper(false) + .build(); + builder.jsonMessageConverter(new JacksonJsonHttpMessageConverter(jsonMapper)) + .xmlMessageConverter(new JacksonXmlHttpMessageConverter(xmlMapper)); } } // end::snippet[] diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.kt index c1993d1208c..d090603dea6 100644 --- a/framework-docs/src/main/kotlin/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.kt +++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.kt @@ -2,26 +2,32 @@ package org.springframework.docs.web.webmvc.mvcconfig.mvcconfigmessageconverters -import com.fasterxml.jackson.module.paramnames.ParameterNamesModule import org.springframework.context.annotation.Configuration -import org.springframework.http.converter.HttpMessageConverter -import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter -import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter +import org.springframework.http.converter.HttpMessageConverters +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter +import org.springframework.http.converter.xml.JacksonXmlHttpMessageConverter import org.springframework.web.servlet.config.annotation.WebMvcConfigurer +import tools.jackson.databind.SerializationFeature +import tools.jackson.databind.json.JsonMapper +import tools.jackson.dataformat.xml.XmlMapper import java.text.SimpleDateFormat // tag::snippet[] @Configuration class WebConfiguration : WebMvcConfigurer { - override fun configureMessageConverters(converters: MutableList>) { - val builder = Jackson2ObjectMapperBuilder() - .indentOutput(true) - .dateFormat(SimpleDateFormat("yyyy-MM-dd")) - .modulesToInstall(ParameterNamesModule()) - converters.add(MappingJackson2HttpMessageConverter(builder.build())) - converters.add(MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())) + override fun configureMessageConverters(builder: HttpMessageConverters.Builder) { + val jsonMapper = JsonMapper.builder() + .findAndAddModules() + .enable(SerializationFeature.INDENT_OUTPUT) + .defaultDateFormat(SimpleDateFormat("yyyy-MM-dd")) + .build() + val xmlMapper = XmlMapper.builder() + .findAndAddModules() + .defaultUseWrapper(false) + .build() + builder.jsonMessageConverter(JacksonJsonHttpMessageConverter(jsonMapper)) + .xmlMessageConverter(JacksonXmlHttpMessageConverter(xmlMapper)) } } // end::snippet[] \ No newline at end of file diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.xml deleted file mode 100644 index f63d2aab1ff..00000000000 --- a/framework-docs/src/main/resources/org/springframework/docs/web/webmvc/mvcconfig/mvcconfigmessageconverters/WebConfiguration.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file