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

2022-08-31 08:59:43

我正在使用Spring Boot(1.2.1),其方式与他们的Building a RESTful Web Service教程类似:

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

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

但我想对JSON格式进行一些简单的自定义,例如:

setSerializationInclusion(JsonInclude.Include.NON_NULL)

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

我在这篇博客文章中尝试了这种方法,创建了一个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配合使用。


答案 1

您可以通过以下方式配置属性包含以及许多其他设置:application.properties

spring.jackson.default-property-inclusion=non_null

文档中有一个表列出了所有可以使用的属性。

如果您想要更多的控制,您还可以使用Bean以编程方式自定义Spring Boot的配置,如文档中所述:Jackson2ObjectMapperBuilderCustomizer

上下文可以由一个或多个 Bean 自定义。可以订购此类定制器 Bean(Boot 自己的定制器的顺序为 0),允许在 Boot 的自定义之前和之后应用其他自定义。Jackson2ObjectMapperBuilderJackson2ObjectMapperBuilderCustomizer

最后,如果您不需要 Boot 的任何配置,并希望完全控制其配置方式,请声明您自己的 Bean:ObjectMapperJackson2ObjectMapperBuilder

@Bean
Jackson2ObjectMapperBuilder objectMapperBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    // Configure the builder to suit your needs
    return builder;
}

答案 2

我对这个问题的回答有点晚,但将来有人可能会发现这很有用。除了许多其他方法之外,下面的方法效果最好,我个人认为更适合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()));
    }
}

推荐