如何自定义由Spring Boot隐式使用的Jackson JSON映射器?

我正在使用Spring Boot(1.2.1),与构buildREST风格的Web服务教程的方式类似:

@RestController public class EventController { @RequestMapping("/events/all") EventList events() { return proxyService.getAllEvents(); } } 

所以上面,Spring MVC隐式地使用Jackson将我的EventList对象序列化为JSON。

但是我想对JSON格式做一些简单的定制,比如:

 setSerializationInclusion(JsonInclude.Include.NON_NULL) 

问题是, 定制隐式JSON映射器的最简单方法什么?

我在这篇博文中尝试了这个方法,创build了一个CustomObjectMapper等等,但是第3步“在Spring上下文中注册类”却失败了:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jacksonFix': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.acme.project.JacksonFix.setAnnotationMethodHandlerAdapter(org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} 

看起来这些指令是针对Spring MVC的旧版本的,而我正在寻找一种简单的方法来实现最新的Spring Boot。

如果您使用Spring Boot 1.3或更新版本,则可以通过application.propertiesconfiguration序列化包含:

 spring.jackson.serialization-inclusion=non_null 

请参阅Spring Boot文档中的“ 自定义Jackson ObjectMapper ”一节。

如果您使用Spring Boot的早期版本,那么在Spring Boot中configuration序列化最简单的方法是声明您自己的,适当configuration的Jackson2ObjectMapperBuilder bean。 例如:

 @Bean public Jackson2ObjectMapperBuilder objectMapperBuilder() { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.serializationInclusion(JsonInclude.Include.NON_NULL); return builder; } 

很多东西都可以在应用程序属性中configuration。 不幸的是,这个function只在版本1.3,但你可以添加一个configuration类

 @Autowired(required = true) public void configeJackson(ObjectMapper jackson2ObjectMapper) { jackson2ObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); } 

[更新:您必须在ObjectMapper上工作,因为build()方法在configuration运行之前被调用。]

我对这个问题回答得有点晚,但是将来有人会觉得这个有用。 下面的方法,除了很多其他的方法,效果最好,我个人认为会更适合一个Web应用程序。

 @Configuration @EnableWebMvc public class WebConfiguration extends WebMvcConfigurerAdapter { ... other configurations @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.serializationInclusion(JsonInclude.Include.NON_NULL); builder.propertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); builder.serializationInclusion(Include.NON_EMPTY); builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd")); converters.add(new MappingJackson2HttpMessageConverter(builder.build())); converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); } } 

该文件指出了几种方法来做到这一点。

如果要完全replace默认的ObjectMapper ,请定义该types的@Bean并将其标记为@Primary

定义@Beantypes的Jackson2ObjectMapperBuilder将允许您自定义默认的ObjectMapperXmlMapper (分别在MappingJackson2HttpMessageConverterMappingJackson2XmlHttpMessageConverter使用)。

spring.jackson.serialization-inclusion=non_null用于为我们工作

但是,当我们将弹簧启动版本升级到1.4.2.RELEASE或更高版本时,它停止工作。

现在另一个属性spring.jackson.default-property-inclusion=non_null正在做魔术。

实际上, serialization-inclusion已被弃用。 这就是我的智慧给我的。

已弃用:ObjectMapper.setSerializationInclusion已在Jackson 2.7中弃用

所以,开始使用spring.jackson.default-property-inclusion=non_null来代替

我偶然发现了另一个很好的解决scheme。

基本上,只有从提到的博客张贴第2步 ,并定义一个自定义ObjectMapper作为Spring @Component 。 (事情开始工作,当我刚刚从第3步删除所有AnnotationMethodHandlerAdapter的东西。)

 @Component @Primary public class CustomObjectMapper extends ObjectMapper { public CustomObjectMapper() { setSerializationInclusion(JsonInclude.Include.NON_NULL); configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } } 

只要组件位于Spring扫描的软件包中就可以使用。 (在我的情况下,使用@Primary不是强制性的,但为什么不明确说明)

对我来说,与其他方法相比,有两个好处:

  • 这比较简单。 我只能从jackson扩展一个类,而不需要知道像Jackson2ObjectMapperBuilder这样的高度特定于Spring的东西。
  • 我想在我的应用程序的另一部分中使用相同的Jacksonconfiguration来反序列化JSON,这样就非常简单: new CustomObjectMapper()而不是new ObjectMapper()

我发现上述解决scheme:

spring.jackson.serialization系夹杂物= non_null

只能从1.4.0.RELEASE版本的spring启动开始工作。 在所有其他情况下,configuration被忽略。

我通过对弹簧靴样本“spring-boot-sample-jersey”的修改进行了实验,

我知道要求Spring引导的问题,但我相信很多人在非Spring引导中寻找如何做到这一点,就像我几乎整天search一样。

如果只打算configurationObjectMapper ,则在Spring 4之上,不需要configurationMappingJacksonHttpMessageConverter

你只需要做:

 public class MyObjectMapper extends ObjectMapper { private static final long serialVersionUID = 4219938065516862637L; public MyObjectMapper() { super(); enable(SerializationFeature.INDENT_OUTPUT); } } 

在你的Springconfiguration中,创build这个bean:

 @Bean public MyObjectMapper myObjectMapper() { return new MyObjectMapper(); }