PageRenderTime 50ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://gitlab.com/zouxc/spring-framework
Java | 375 lines | 115 code | 38 blank | 222 comment | 4 complexity | 21940fd9a71a8e1f908116d838eaec59 MD5 | raw file
  1. /*
  2. * Copyright 2002-2014 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.http.converter.json;
  17. import java.text.DateFormat;
  18. import java.text.SimpleDateFormat;
  19. import java.util.List;
  20. import java.util.Map;
  21. import com.fasterxml.jackson.annotation.JsonInclude;
  22. import com.fasterxml.jackson.databind.AnnotationIntrospector;
  23. import com.fasterxml.jackson.databind.DeserializationFeature;
  24. import com.fasterxml.jackson.databind.JsonDeserializer;
  25. import com.fasterxml.jackson.databind.JsonSerializer;
  26. import com.fasterxml.jackson.databind.MapperFeature;
  27. import com.fasterxml.jackson.databind.Module;
  28. import com.fasterxml.jackson.databind.ObjectMapper;
  29. import com.fasterxml.jackson.databind.PropertyNamingStrategy;
  30. import com.fasterxml.jackson.databind.SerializationFeature;
  31. import com.fasterxml.jackson.dataformat.xml.XmlMapper;
  32. import org.springframework.beans.factory.BeanClassLoaderAware;
  33. import org.springframework.beans.factory.FactoryBean;
  34. import org.springframework.beans.factory.InitializingBean;
  35. /**
  36. * A {@link FactoryBean} for creating a Jackson 2.x {@link ObjectMapper} (default) or
  37. * {@link XmlMapper} ({@code createXmlMapper} property set to true) with setters
  38. * to enable or disable Jackson features from within XML configuration.
  39. *
  40. * <p>It customizes Jackson defaults properties with the following ones:
  41. * <ul>
  42. * <li>{@link MapperFeature#DEFAULT_VIEW_INCLUSION} is disabled</li>
  43. * <li>{@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} is disabled</li>
  44. * </ul>
  45. *
  46. * <p>Example usage with
  47. * {@link MappingJackson2HttpMessageConverter}:
  48. *
  49. * <pre class="code">
  50. * &lt;bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
  51. * &lt;property name="objectMapper">
  52. * &lt;bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
  53. * p:autoDetectFields="false"
  54. * p:autoDetectGettersSetters="false"
  55. * p:annotationIntrospector-ref="jaxbAnnotationIntrospector" />
  56. * &lt;/property>
  57. * &lt;/bean>
  58. * </pre>
  59. *
  60. * <p>Example usage with MappingJackson2JsonView:
  61. *
  62. * <pre class="code">
  63. * &lt;bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
  64. * &lt;property name="objectMapper">
  65. * &lt;bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
  66. * p:failOnEmptyBeans="false"
  67. * p:indentOutput="true">
  68. * &lt;property name="serializers">
  69. * &lt;array>
  70. * &lt;bean class="org.mycompany.MyCustomSerializer" />
  71. * &lt;/array>
  72. * &lt;/property>
  73. * &lt;/bean>
  74. * &lt;/property>
  75. * &lt;/bean>
  76. * </pre>
  77. *
  78. * <p>In case there are no specific setters provided (for some rarely used options),
  79. * you can still use the more general methods {@link #setFeaturesToEnable} and
  80. * {@link #setFeaturesToDisable}.
  81. *
  82. * <pre class="code">
  83. * &lt;bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
  84. * &lt;property name="featuresToEnable">
  85. * &lt;array>
  86. * &lt;util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature$WRAP_ROOT_VALUE"/>
  87. * &lt;util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature$CLOSE_CLOSEABLE"/>
  88. * &lt;/array>
  89. * &lt;/property>
  90. * &lt;property name="featuresToDisable">
  91. * &lt;array>
  92. * &lt;util:constant static-field="com.fasterxml.jackson.databind.MapperFeature$USE_ANNOTATIONS"/>
  93. * &lt;/array>
  94. * &lt;/property>
  95. * &lt;/bean>
  96. * </pre>
  97. *
  98. * <p>In case you want to configure Jackson's {@link ObjectMapper} with a custom {@link Module},
  99. * you can register one or more such Modules by class name via {@link #setModulesToInstall}:
  100. *
  101. * <pre class="code">
  102. * &lt;bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
  103. * &lt;property name="modulesToInstall" value="myapp.jackson.MySampleModule,myapp.jackson.MyOtherModule"/>
  104. * &lt;/bean
  105. * </pre>
  106. *
  107. * Note that Jackson's JSR-310 and Joda-Time support modules will be registered automatically
  108. * when available (and when Java 8 and Joda-Time themselves are available, respectively).
  109. *
  110. * <p>Tested against Jackson 2.2, 2.3 and 2.4; compatible with Jackson 2.0 and higher.
  111. *
  112. * @author <a href="mailto:dmitry.katsubo@gmail.com">Dmitry Katsubo</a>
  113. * @author Rossen Stoyanchev
  114. * @author Brian Clozel
  115. * @author Juergen Hoeller
  116. * @author Tadaya Tsuyukubo
  117. * @since 3.2
  118. */
  119. public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>, BeanClassLoaderAware, InitializingBean {
  120. private final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
  121. private ObjectMapper objectMapper;
  122. /**
  123. * Set the {@link ObjectMapper} instance to use. If not set, the {@link ObjectMapper}
  124. * will be created using its default constructor.
  125. */
  126. public void setObjectMapper(ObjectMapper objectMapper) {
  127. this.objectMapper = objectMapper;
  128. }
  129. /**
  130. * If set to true and no custom {@link ObjectMapper} has been set, a {@link XmlMapper}
  131. * will be created using its default constructor.
  132. * @since 4.1
  133. */
  134. public void setCreateXmlMapper(boolean createXmlMapper) {
  135. this.builder.createXmlMapper(createXmlMapper);
  136. }
  137. /**
  138. * Define the format for date/time with the given {@link DateFormat}.
  139. * <p>Note: Setting this property makes the exposed {@link ObjectMapper}
  140. * non-thread-safe, according to Jackson's thread safety rules.
  141. * @see #setSimpleDateFormat(String)
  142. */
  143. public void setDateFormat(DateFormat dateFormat) {
  144. this.builder.dateFormat(dateFormat);
  145. }
  146. /**
  147. * Define the date/time format with a {@link SimpleDateFormat}.
  148. * <p>Note: Setting this property makes the exposed {@link ObjectMapper}
  149. * non-thread-safe, according to Jackson's thread safety rules.
  150. * @see #setDateFormat(DateFormat)
  151. */
  152. public void setSimpleDateFormat(String format) {
  153. this.builder.simpleDateFormat(format);
  154. }
  155. /**
  156. * Set an {@link AnnotationIntrospector} for both serialization and deserialization.
  157. */
  158. public void setAnnotationIntrospector(AnnotationIntrospector annotationIntrospector) {
  159. this.builder.annotationIntrospector(annotationIntrospector);
  160. }
  161. /**
  162. * Specify a {@link com.fasterxml.jackson.databind.PropertyNamingStrategy} to
  163. * configure the {@link ObjectMapper} with.
  164. * @since 4.0.2
  165. */
  166. public void setPropertyNamingStrategy(PropertyNamingStrategy propertyNamingStrategy) {
  167. this.builder.propertyNamingStrategy(propertyNamingStrategy);
  168. }
  169. /**
  170. * Set a custom inclusion strategy for serialization.
  171. * @see com.fasterxml.jackson.annotation.JsonInclude.Include
  172. */
  173. public void setSerializationInclusion(JsonInclude.Include serializationInclusion) {
  174. this.builder.serializationInclusion(serializationInclusion);
  175. }
  176. /**
  177. * Configure custom serializers. Each serializer is registered for the type
  178. * returned by {@link JsonSerializer#handledType()}, which must not be
  179. * {@code null}.
  180. * @see #setSerializersByType(Map)
  181. */
  182. public void setSerializers(JsonSerializer<?>... serializers) {
  183. this.builder.serializers(serializers);
  184. }
  185. /**
  186. * Configure custom serializers for the given types.
  187. * @see #setSerializers(JsonSerializer...)
  188. */
  189. public void setSerializersByType(Map<Class<?>, JsonSerializer<?>> serializers) {
  190. this.builder.serializersByType(serializers);
  191. }
  192. /**
  193. * Configure custom deserializers for the given types.
  194. */
  195. public void setDeserializersByType(Map<Class<?>, JsonDeserializer<?>> deserializers) {
  196. this.builder.deserializersByType(deserializers);
  197. }
  198. /**
  199. * Add mix-in annotations to use for augmenting specified class or interface.
  200. * @param mixIns Map of entries with target classes (or interface) whose annotations
  201. * to effectively override as key and mix-in classes (or interface) whose
  202. * annotations are to be "added" to target's annotations as value.
  203. * @since 4.1.2
  204. * @see com.fasterxml.jackson.databind.ObjectMapper#addMixInAnnotations(Class, Class)
  205. */
  206. public void setMixIns(Map<Class<?>, Class<?>> mixIns) {
  207. this.builder.mixIns(mixIns);
  208. }
  209. /**
  210. * Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option.
  211. */
  212. public void setAutoDetectFields(boolean autoDetectFields) {
  213. this.builder.autoDetectFields(autoDetectFields);
  214. }
  215. /**
  216. * Shortcut for {@link MapperFeature#AUTO_DETECT_SETTERS}/
  217. * {@link MapperFeature#AUTO_DETECT_GETTERS} option.
  218. */
  219. public void setAutoDetectGettersSetters(boolean autoDetectGettersSetters) {
  220. this.builder.autoDetectGettersSetters(autoDetectGettersSetters);
  221. }
  222. /**
  223. * Shortcut for {@link MapperFeature#DEFAULT_VIEW_INCLUSION} option.
  224. * @since 4.1
  225. */
  226. public void setDefaultViewInclusion(boolean defaultViewInclusion) {
  227. this.builder.defaultViewInclusion(defaultViewInclusion);
  228. }
  229. /**
  230. * Shortcut for {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} option.
  231. * @since 4.1.1
  232. */
  233. public void setFailOnUnknownProperties(boolean failOnUnknownProperties) {
  234. this.builder.failOnUnknownProperties(failOnUnknownProperties);
  235. }
  236. /**
  237. * Shortcut for {@link SerializationFeature#FAIL_ON_EMPTY_BEANS} option.
  238. */
  239. public void setFailOnEmptyBeans(boolean failOnEmptyBeans) {
  240. this.builder.failOnEmptyBeans(failOnEmptyBeans);
  241. }
  242. /**
  243. * Shortcut for {@link SerializationFeature#INDENT_OUTPUT} option.
  244. */
  245. public void setIndentOutput(boolean indentOutput) {
  246. this.builder.indentOutput(indentOutput);
  247. }
  248. /**
  249. * Specify features to enable.
  250. * @see com.fasterxml.jackson.core.JsonParser.Feature
  251. * @see com.fasterxml.jackson.core.JsonGenerator.Feature
  252. * @see com.fasterxml.jackson.databind.SerializationFeature
  253. * @see com.fasterxml.jackson.databind.DeserializationFeature
  254. * @see com.fasterxml.jackson.databind.MapperFeature
  255. */
  256. public void setFeaturesToEnable(Object... featuresToEnable) {
  257. this.builder.featuresToEnable(featuresToEnable);
  258. }
  259. /**
  260. * Specify features to disable.
  261. * @see com.fasterxml.jackson.core.JsonParser.Feature
  262. * @see com.fasterxml.jackson.core.JsonGenerator.Feature
  263. * @see com.fasterxml.jackson.databind.SerializationFeature
  264. * @see com.fasterxml.jackson.databind.DeserializationFeature
  265. * @see com.fasterxml.jackson.databind.MapperFeature
  266. */
  267. public void setFeaturesToDisable(Object... featuresToDisable) {
  268. this.builder.featuresToDisable(featuresToDisable);
  269. }
  270. /**
  271. * Set a complete list of modules to be registered with the {@link ObjectMapper}.
  272. * <p>Note: If this is set, no finding of modules is going to happen - not by
  273. * Jackson, and not by Spring either (see {@link #setFindModulesViaServiceLoader}).
  274. * As a consequence, specifying an empty list here will suppress any kind of
  275. * module detection.
  276. * <p>Specify either this or {@link #setModulesToInstall}, not both.
  277. * @since 4.0
  278. * @see com.fasterxml.jackson.databind.Module
  279. */
  280. public void setModules(List<Module> modules) {
  281. this.builder.modules(modules);
  282. }
  283. /**
  284. * Specify one or more modules by class (or class name in XML),
  285. * to be registered with the {@link ObjectMapper}.
  286. * <p>Modules specified here will be registered in combination with
  287. * Spring's autodetection of JSR-310 and Joda-Time, or Jackson's
  288. * finding of modules (see {@link #setFindModulesViaServiceLoader}).
  289. * <p>Specify either this or {@link #setModules}, not both.
  290. * @since 4.0.1
  291. * @see com.fasterxml.jackson.databind.Module
  292. */
  293. public void setModulesToInstall(Class<? extends Module>... modules) {
  294. this.builder.modulesToInstall(modules);
  295. }
  296. /**
  297. * Set whether to let Jackson find available modules via the JDK ServiceLoader,
  298. * based on META-INF metadata in the classpath. Requires Jackson 2.2 or higher.
  299. * <p>If this mode is not set, Spring's Jackson2ObjectMapperFactoryBean itself
  300. * will try to find the JSR-310 and Joda-Time support modules on the classpath -
  301. * provided that Java 8 and Joda-Time themselves are available, respectively.
  302. * @since 4.0.1
  303. * @see com.fasterxml.jackson.databind.ObjectMapper#findModules()
  304. */
  305. public void setFindModulesViaServiceLoader(boolean findModules) {
  306. this.builder.findModulesViaServiceLoader(findModules);
  307. }
  308. @Override
  309. public void setBeanClassLoader(ClassLoader beanClassLoader) {
  310. this.builder.moduleClassLoader(beanClassLoader);
  311. }
  312. @Override
  313. @SuppressWarnings("unchecked")
  314. public void afterPropertiesSet() {
  315. if (this.objectMapper != null) {
  316. this.builder.configure(this.objectMapper);
  317. }
  318. else {
  319. this.objectMapper = this.builder.build();
  320. }
  321. }
  322. /**
  323. * Return the singleton ObjectMapper.
  324. */
  325. @Override
  326. public ObjectMapper getObject() {
  327. return this.objectMapper;
  328. }
  329. @Override
  330. public Class<?> getObjectType() {
  331. return (this.objectMapper != null ? this.objectMapper.getClass() : null);
  332. }
  333. @Override
  334. public boolean isSingleton() {
  335. return true;
  336. }
  337. }