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 283215fb5ad5a4880ccf9d42be0bb848de87ba66..627fdf52db8b1e4873d9e160cb906219e40e8bd4 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 @@ -60,6 +60,7 @@ import org.springframework.util.ClassUtils; * * @author Sebastien Deleuze * @author Juergen Hoeller + * @author Tadaya Tsuyukubo * @since 4.1.1 * @see #build() * @see #configure(ObjectMapper) @@ -81,6 +82,8 @@ public class Jackson2ObjectMapperBuilder { private final Map, JsonDeserializer> deserializers = new LinkedHashMap, JsonDeserializer>(); + private final Map, Class> mixIns = new HashMap, Class>(); + private final Map features = new HashMap(); private List modules; @@ -190,6 +193,21 @@ public class Jackson2ObjectMapperBuilder { return this; } + /** + * Add mix-in annotations to use for augmenting specified class or interface. + * @param mixIns Map of entries with target classes (or interface) whose annotations + * to effectively override as key and mix-in classes (or interface) whose + * annotations are to be "added" to target's annotations as value. + * @since 4.1.2 + * @see com.fasterxml.jackson.databind.ObjectMapper#addMixInAnnotations(Class, Class) + */ + public Jackson2ObjectMapperBuilder mixIns(Map, Class> mixIns) { + if (mixIns != null) { + this.mixIns.putAll(mixIns); + } + return this; + } + /** * Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option. */ @@ -414,6 +432,9 @@ public class Jackson2ObjectMapperBuilder { if (this.propertyNamingStrategy != null) { objectMapper.setPropertyNamingStrategy(this.propertyNamingStrategy); } + for (Class target : this.mixIns.keySet()) { + objectMapper.addMixInAnnotations(target, this.mixIns.get(target)); + } } @SuppressWarnings("unchecked") diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java index 7b86daddd30ff2886c5f16912bb5e30191fe0543..726756c75fc8af78e5d33b950087c2e05045e4c7 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java @@ -118,6 +118,7 @@ import org.springframework.beans.factory.InitializingBean; * @author Rossen Stoyanchev * @author Brian Clozel * @author Juergen Hoeller + * @author Tadaya Tsuyukubo * @since 3.2 */ public class Jackson2ObjectMapperFactoryBean implements FactoryBean, BeanClassLoaderAware, InitializingBean { @@ -213,6 +214,18 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean, Class> mixIns) { + this.builder.mixIns(mixIns); + } + /** * Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option. */ 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 d70518aa87ff45048ac442c814dc311042f7f628..2be4732970d2363996fcca43af34afe1bcdf8ea1 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 @@ -190,6 +190,19 @@ public class Jackson2ObjectMapperBuilderTests { assertSame(strategy, objectMapper.getDeserializationConfig().getPropertyNamingStrategy()); } + @Test + public void mixIns() { + Class target = String.class; + Class mixinSource = Object.class; + Map, Class> mixIns = new HashMap, Class>(); + mixIns.put(target, mixinSource); + + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().mixIns(mixIns).build(); + + assertEquals(1, objectMapper.mixInCount()); + assertSame(mixinSource, objectMapper.findMixInClassFor(target)); + } + @Test public void completeSetup() { NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance; diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java index daee3296afab09a80bcacb80f70a677e444b7677..011384f4c2bf2662889813f2fe408deb6a5faedc 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java @@ -207,6 +207,21 @@ public class Jackson2ObjectMapperFactoryBeanTests { assertSame(strategy, this.factory.getObject().getDeserializationConfig().getPropertyNamingStrategy()); } + @Test + public void setMixIns() { + Class target = String.class; + Class mixinSource = Object.class; + Map, Class> mixIns = new HashMap, Class>(); + mixIns.put(target, mixinSource); + + this.factory.setMixIns(mixIns); + this.factory.afterPropertiesSet(); + ObjectMapper objectMapper = this.factory.getObject(); + + assertEquals(1, objectMapper.mixInCount()); + assertSame(mixinSource, objectMapper.findMixInClassFor(target)); + } + @Test public void completeSetup() { NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance;