From e88eb0ecf77b4973d4923367d5a939457cf578ac Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 13 May 2020 11:15:43 +0100 Subject: [PATCH] Option for advanced ObjectMapper customization Closes gh-23017 --- .../json/Jackson2ObjectMapperBuilder.java | 21 +++++++++++++++++++ .../Jackson2ObjectMapperBuilderTests.java | 15 +++++++++++++ 2 files changed, 36 insertions(+) diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java index 6796455e05..e480e9ba7f 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; +import java.util.function.Consumer; import java.util.function.Function; import com.fasterxml.jackson.annotation.JsonAutoDetect; @@ -169,6 +170,9 @@ public class Jackson2ObjectMapperBuilder { @Nullable private Boolean defaultUseWrapper; + @Nullable + private Consumer configurer; + /** * If set to {@code true}, an {@link XmlMapper} will be created using its @@ -639,6 +643,19 @@ public class Jackson2ObjectMapperBuilder { return this; } + /** + * An option to apply additional customizations directly to the + * {@code ObjectMapper} instances at the end, after all other config + * properties of the builder have been applied. + * @param configurer a configurer to apply; if invoked multiple times, all + * configurers are applied in the same order. + * @since 5.3 + */ + public Jackson2ObjectMapperBuilder postConfigurer(Consumer configurer) { + this.configurer = (this.configurer != null ? this.configurer.andThen(configurer) : configurer); + return this; + } + /** * Build a new {@link ObjectMapper} instance. @@ -740,6 +757,10 @@ public class Jackson2ObjectMapperBuilder { objectMapper.setHandlerInstantiator( new SpringHandlerInstantiator(this.applicationContext.getAutowireCapableBeanFactory())); } + + if (this.configurer != null) { + this.configurer.accept(objectMapper); + } } private void registerModule(Module module, MultiValueMap modulesToRegister) { diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java index dc3f43189d..9399d8e78b 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java @@ -62,6 +62,7 @@ import com.fasterxml.jackson.databind.deser.BasicDeserializerFactory; import com.fasterxml.jackson.databind.deser.Deserializers; import com.fasterxml.jackson.databind.deser.std.DateDeserializers; import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.module.SimpleSerializers; @@ -431,6 +432,20 @@ public class Jackson2ObjectMapperBuilderTests { assertThat(output).doesNotContain("value2"); } + @Test // gh-23017 + public void postConfigurer() { + + JacksonAnnotationIntrospector introspector1 = new JacksonAnnotationIntrospector(); + JacksonAnnotationIntrospector introspector2 = new JacksonAnnotationIntrospector(); + + ObjectMapper mapper = Jackson2ObjectMapperBuilder.json() + .postConfigurer(m -> m.setAnnotationIntrospectors(introspector1, introspector2)) + .build(); + + assertThat(mapper.getSerializationConfig().getAnnotationIntrospector()).isSameAs(introspector1); + assertThat(mapper.getDeserializationConfig().getAnnotationIntrospector()).isSameAs(introspector2); + } + @Test public void completeSetup() throws JsonMappingException { NopAnnotationIntrospector introspector = NopAnnotationIntrospector.instance;