Skip to content

Commit 25bb58a

Browse files
ttddyysdeleuze
authored andcommitted
Add shortcuts for Jackson mix-in annotations registration
This commit adds support for direct Jackson mix-in annotations registration in Jackson2ObjectMapperFactoryBean and Jackson2ObjectMapperBuilder. Issue: SPR-12144
1 parent 5a63117 commit 25bb58a

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
*
6161
* @author Sebastien Deleuze
6262
* @author Juergen Hoeller
63+
* @author Tadaya Tsuyukubo
6364
* @since 4.1.1
6465
* @see #build()
6566
* @see #configure(ObjectMapper)
@@ -81,6 +82,8 @@ public class Jackson2ObjectMapperBuilder {
8182

8283
private final Map<Class<?>, JsonDeserializer<?>> deserializers = new LinkedHashMap<Class<?>, JsonDeserializer<?>>();
8384

85+
private final Map<Class<?>, Class<?>> mixIns = new HashMap<Class<?>, Class<?>>();
86+
8487
private final Map<Object, Boolean> features = new HashMap<Object, Boolean>();
8588

8689
private List<Module> modules;
@@ -190,6 +193,21 @@ public Jackson2ObjectMapperBuilder deserializersByType(Map<Class<?>, JsonDeseria
190193
return this;
191194
}
192195

196+
/**
197+
* Add mix-in annotations to use for augmenting specified class or interface.
198+
* @param mixIns Map of entries with target classes (or interface) whose annotations
199+
* to effectively override as key and mix-in classes (or interface) whose
200+
* annotations are to be "added" to target's annotations as value.
201+
* @since 4.1.2
202+
* @see com.fasterxml.jackson.databind.ObjectMapper#addMixInAnnotations(Class, Class)
203+
*/
204+
public Jackson2ObjectMapperBuilder mixIns(Map<Class<?>, Class<?>> mixIns) {
205+
if (mixIns != null) {
206+
this.mixIns.putAll(mixIns);
207+
}
208+
return this;
209+
}
210+
193211
/**
194212
* Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option.
195213
*/
@@ -414,6 +432,9 @@ public void configure(ObjectMapper objectMapper) {
414432
if (this.propertyNamingStrategy != null) {
415433
objectMapper.setPropertyNamingStrategy(this.propertyNamingStrategy);
416434
}
435+
for (Class<?> target : this.mixIns.keySet()) {
436+
objectMapper.addMixInAnnotations(target, this.mixIns.get(target));
437+
}
417438
}
418439

419440
@SuppressWarnings("unchecked")

spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
* @author Rossen Stoyanchev
119119
* @author Brian Clozel
120120
* @author Juergen Hoeller
121+
* @author Tadaya Tsuyukubo
121122
* @since 3.2
122123
*/
123124
public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>, BeanClassLoaderAware, InitializingBean {
@@ -213,6 +214,18 @@ public void setDeserializersByType(Map<Class<?>, JsonDeserializer<?>> deserializ
213214
this.builder.deserializersByType(deserializers);
214215
}
215216

217+
/**
218+
* Add mix-in annotations to use for augmenting specified class or interface.
219+
* @param mixIns Map of entries with target classes (or interface) whose annotations
220+
* to effectively override as key and mix-in classes (or interface) whose
221+
* annotations are to be "added" to target's annotations as value.
222+
* @since 4.1.2
223+
* @see com.fasterxml.jackson.databind.ObjectMapper#addMixInAnnotations(Class, Class)
224+
*/
225+
public void setMixIns(Map<Class<?>, Class<?>> mixIns) {
226+
this.builder.mixIns(mixIns);
227+
}
228+
216229
/**
217230
* Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option.
218231
*/

spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilderTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,19 @@ public void propertyNamingStrategy() {
190190
assertSame(strategy, objectMapper.getDeserializationConfig().getPropertyNamingStrategy());
191191
}
192192

193+
@Test
194+
public void mixIns() {
195+
Class<?> target = String.class;
196+
Class<?> mixinSource = Object.class;
197+
Map<Class<?>, Class<?>> mixIns = new HashMap<Class<?>, Class<?>>();
198+
mixIns.put(target, mixinSource);
199+
200+
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().mixIns(mixIns).build();
201+
202+
assertEquals(1, objectMapper.mixInCount());
203+
assertSame(mixinSource, objectMapper.findMixInClassFor(target));
204+
}
205+
193206
@Test
194207
public void completeSetup() {
195208
NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance;

spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,21 @@ public void propertyNamingStrategy() {
207207
assertSame(strategy, this.factory.getObject().getDeserializationConfig().getPropertyNamingStrategy());
208208
}
209209

210+
@Test
211+
public void setMixIns() {
212+
Class<?> target = String.class;
213+
Class<?> mixinSource = Object.class;
214+
Map<Class<?>, Class<?>> mixIns = new HashMap<Class<?>, Class<?>>();
215+
mixIns.put(target, mixinSource);
216+
217+
this.factory.setMixIns(mixIns);
218+
this.factory.afterPropertiesSet();
219+
ObjectMapper objectMapper = this.factory.getObject();
220+
221+
assertEquals(1, objectMapper.mixInCount());
222+
assertSame(mixinSource, objectMapper.findMixInClassFor(target));
223+
}
224+
210225
@Test
211226
public void completeSetup() {
212227
NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance;

0 commit comments

Comments
 (0)