From 11b3fe22893eb2a5e1540d17a005996629e681aa Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 4 Jan 2014 23:29:05 +0100 Subject: [PATCH] Added setModulesToInstall with convenient Class vararg, renamed setFindModules to setFindModulesViaServiceLoader, made existing setModules override any other setting Issue: SPR-11040 --- .../json/Jackson2ObjectMapperFactoryBean.java | 84 +++++++++++++------ 1 file changed, 59 insertions(+), 25 deletions(-) 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 0cdad795f4..506511694d 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 @@ -114,6 +114,8 @@ import org.springframework.util.ClassUtils; * </bean> * * + *

Tested against Jackson 2.2 and 2.3; compatible with Jackson 2.0 and higher. + * * @author Dmitry Katsubo * @author Rossen Stoyanchev * @author Brian Clozel @@ -136,9 +138,11 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean features = new HashMap(); - private final List modules = new LinkedList(); + private List modules; - private boolean findModules; + private Class[] modulesToInstall; + + private boolean findModulesViaServiceLoader; private ClassLoader beanClassLoader; @@ -285,26 +289,44 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBeanIf this mode is not set, Spring's Jackson2ObjectMapperFactoryBean itself - * will try to find the JSR-310 and Joda-Time support modules on the classpath - - * provided that Java 8 and Joda-Time themselves are available, respectively. - * @see com.fasterxml.jackson.databind.ObjectMapper#findModules() - */ - public void setFindModules(boolean findModules) { - this.findModules = findModules; - } - - /** - * Set the list of modules to be registered with the {@link ObjectMapper}. + * Set a complete list of modules to be registered with the {@link ObjectMapper}. + *

Note: If this is set, no finding of modules is going to happen - not by + * Jackson, and not by Spring either (see {@link #setFindModulesViaServiceLoader}). + * As a consequence, specifying an empty list here will suppress any kind of + * module detection. + *

Specify either this or {@link #setModulesToInstall}, not both. * @since 4.0 * @see com.fasterxml.jackson.databind.Module */ public void setModules(List modules) { - if (modules != null) { - this.modules.addAll(modules); - } + this.modules = new LinkedList(modules); + } + + /** + * Specify one or more modules by class (or class name in XML), + * to be registered with the {@link ObjectMapper}. + *

Modules specified here will be registered in combination with + * Spring's autodetection of JSR-310 and Joda-Time, or Jackson's + * finding of modules (see {@link #setFindModulesViaServiceLoader}). + *

Specify either this or {@link #setModules}, not both. + * @since 4.0.1 + * @see com.fasterxml.jackson.databind.Module + */ + public void setModulesToInstall(Class... modules) { + this.modulesToInstall = modules; + } + + /** + * Set whether to let Jackson find available modules via the JDK ServiceLoader, + * based on META-INF metadata in the classpath. Requires Jackson 2.2 or higher. + *

If this mode is not set, Spring's Jackson2ObjectMapperFactoryBean itself + * will try to find the JSR-310 and Joda-Time support modules on the classpath - + * provided that Java 8 and Joda-Time themselves are available, respectively. + * @since 4.0.1 + * @see com.fasterxml.jackson.databind.ObjectMapper#findModules() + */ + public void setFindModulesViaServiceLoader(boolean findModules) { + this.findModulesViaServiceLoader = findModules; } @Override @@ -342,15 +364,27 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean module : this.modulesToInstall) { + this.objectMapper.registerModule(BeanUtils.instantiate(module)); + } + } + if (this.findModulesViaServiceLoader) { + // Jackson 2.2+ + this.objectMapper.registerModules(ObjectMapper.findModules(this.beanClassLoader)); + } + else { + registerWellKnownModulesIfAvailable(); + } } }