Browse Source

Allow a custom JsonFactory to be used with JsonMapper.Builder

This commit improves the auto-configuration of the JSonMapper.Builder
to accept a custom JsonFactory if a bean of this type is present.

Closes gh-48594
pull/48817/head
Stéphane Nicoll 4 weeks ago
parent
commit
22d6f6a7de
  1. 3
      documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc
  2. 6
      module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java
  3. 20
      module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java

3
documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc

@ -106,7 +106,8 @@ This environment-based configuration is applied to the auto-configured javadoc:t @@ -106,7 +106,8 @@ This environment-based configuration is applied to the auto-configured javadoc:t
To ease the migration when working on an application that previously used Jackson 2, the auto-configured `JsonMapper` can be configured to use defaults that are as close as possible to those that Spring Boot used for Jackson 2. To enable these defaults, set configprop:spring.jackson.use-jackson2-defaults[] to `true`.
The context's javadoc:tools.jackson.databind.json.JsonMapper$Builder[] can be customized by one or more javadoc:org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer[] beans.
If a javadoc:tools.jackson.core.json.JsonFactory[] bean is present, it is used by the context's javadoc:tools.jackson.databind.json.JsonMapper$Builder[].
The builder can also be customized by one or more javadoc:org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer[] beans.
Such customizer beans can be ordered (Boot's own customizer has an order of 0), letting additional customization be applied both before and after Boot's customization.
Any beans of type javadoc:tools.jackson.databind.JacksonModule[] are automatically registered with the auto-configured javadoc:tools.jackson.databind.json.JsonMapper$Builder[] and are applied to any javadoc:tools.jackson.databind.json.JsonMapper[] instances that it creates.

6
module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java

@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect; @@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import org.jspecify.annotations.Nullable;
import tools.jackson.core.json.JsonFactory;
import tools.jackson.databind.JacksonModule;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.PropertyNamingStrategies;
@ -97,8 +98,9 @@ public final class JacksonAutoConfiguration { @@ -97,8 +98,9 @@ public final class JacksonAutoConfiguration {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@ConditionalOnMissingBean
JsonMapper.Builder jsonMapperBuilder(List<JsonMapperBuilderCustomizer> customizers) {
JsonMapper.Builder builder = JsonMapper.builder();
JsonMapper.Builder jsonMapperBuilder(ObjectProvider<JsonFactory> jsonFactory,
List<JsonMapperBuilderCustomizer> customizers) {
JsonMapper.Builder builder = JsonMapper.builder(jsonFactory.getIfAvailable(JsonFactory::new));
customize(builder, customizers);
return builder;
}

20
module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java

@ -34,6 +34,8 @@ import org.junit.jupiter.params.provider.EnumSource; @@ -34,6 +34,8 @@ import org.junit.jupiter.params.provider.EnumSource;
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.StreamReadFeature;
import tools.jackson.core.StreamWriteFeature;
import tools.jackson.core.json.JsonFactory;
import tools.jackson.core.json.JsonFactoryBuilder;
import tools.jackson.core.json.JsonReadFeature;
import tools.jackson.core.json.JsonWriteFeature;
import tools.jackson.databind.DeserializationFeature;
@ -391,6 +393,24 @@ class JacksonAutoConfigurationTests { @@ -391,6 +393,24 @@ class JacksonAutoConfigurationTests {
});
}
@Test
void defaultJsonFactoryIsRegisteredWithTheMapperBuilderWhenNoCustomFactoryExists() {
this.contextRunner.run((context) -> {
Builder jsonMapperBuilder = context.getBean(JsonMapper.Builder.class);
assertThat(jsonMapperBuilder.isEnabled(StreamReadFeature.AUTO_CLOSE_SOURCE)).isTrue();
});
}
@Test
void customJsonFactoryIsRegisteredWithTheMapperBuilder() {
JsonFactory customJsonFactory = new JsonFactoryBuilder().configure(StreamReadFeature.AUTO_CLOSE_SOURCE, false)
.build();
this.contextRunner.withBean("customJsonFactory", JsonFactory.class, () -> customJsonFactory).run((context) -> {
Builder jsonMapperBuilder = context.getBean(JsonMapper.Builder.class);
assertThat(jsonMapperBuilder.isEnabled(StreamReadFeature.AUTO_CLOSE_SOURCE)).isFalse();
});
}
@EnumSource
@ParameterizedTest
void moduleBeansAndWellKnownModulesAreRegisteredWithTheMapperBuilder(MapperType mapperType) {

Loading…
Cancel
Save