如何自定义由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.properties
configuration序列化包含:
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
。定义
@Bean
types的Jackson2ObjectMapperBuilder
将允许您自定义默认的ObjectMapper
和XmlMapper
(分别在MappingJackson2HttpMessageConverter
和MappingJackson2XmlHttpMessageConverter
使用)。
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(); }
- jackson数据绑定枚举不区分大小写
- 将JSONstring转换为使用Jackson的漂亮打印JSON输出
- 如何在Wildfly中configurationJackson?
- 在Spring中编写JSON解串器或者扩展它的正确方法
- jacksonJSON和Hibernate JPA问题的无限recursion
- @JsonProperty字段的注释以及getter / setter
- 不能从START_OBJECT标记反序列化java.util.ArrayList的实例
- 我如何正确使用Jackson ObjectMapper?
- 我应该如何在我的RESTful JAX-RS Web服务中logging未捕获的exception?