在 Spring Boot 应用程序中配置 Jackson mixin
Posted
技术标签:
【中文标题】在 Spring Boot 应用程序中配置 Jackson mixin【英文标题】:Configuring Jackson mixin in Spring Boot application 【发布时间】:2018-12-14 00:39:13 【问题描述】:我为我的班级创建了一个 mixin。 mixin 本身工作正常,这不是大多数人在混合 faterxml/codehaus 注释时遇到的问题。 我在单元测试中对其进行了测试,使用 addMixIn 方法“手动”创建了 ObjectMapper - 它工作得很好。
我想使用该 mixin 来修改从我的 REST 端点返回的响应 json。 我尝试以多种不同的方式自定义 Spring Boot 的 ObjectMapper:
BuilderCustomizer:
@Bean
public Jackson2ObjectMapperBuilderCustomizer addMixin()
return new Jackson2ObjectMapperBuilderCustomizer()
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder)
jacksonObjectMapperBuilder.mixIn(MyClass.class, MyClassMixin.class);
;
建造者:
@Bean
Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder()
return new Jackson2ObjectMapperBuilder().mixIn(MyClass.class, MyClassMixin.class);
转换器:
@Bean
public MappingJackson2HttpMessageConverter configureJackson()
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(MyClass.class, MyClassMixin.class);
converter.setObjectMapper(mapper);
return converter;
对象映射器:
@Autowired(required = true)
public void configureJackon(ObjectMapper jsonMapper)
jsonMapper.addMixIn(MyClass.class, MyClassMixin.class);
这些都不起作用。
【问题讨论】:
【参考方案1】:这可能取决于 Spring Boot 版本,但根据 Customize the Jackson ObjectMapper 定义一个新的 Jackson2ObjectMapperBuilderCustomizer
bean 就足够了
上下文的 Jackson2ObjectMapperBuilder 可以由一个或多个 Jackson2ObjectMapperBuilderCustomizer bean 自定义。可以订购此类定制器 bean(Boot 自己的定制器的顺序为 0),从而在 Boot 定制之前和之后应用额外的定制。
【讨论】:
【参考方案2】:我已经尝试了上述方法,但它也对我不起作用。在调试时,我注意到消息转换器中的 ObjectMapper 为空。
参考帖子get registered message converters,我最终替换了 Jackson 的默认消息转换器,允许我根据需要自定义对象映射器:
@SpringBootApplication
@RestController
public class MixinTest
public static void main(String[] args)
SpringApplication.run(MixinTest.class, args);
static class Person
private String title;
private String name;
private String nullField;
private LocalDate date;
Person(String title, String name)
this.title = title;
this.name = name;
this.date = LocalDate.now();
// getters here...
// this will exclude nullField
@JsonInclude(JsonInclude.Include.NON_NULL)
interface PersonMixin
@JsonProperty("fullName")
String getName();
@Bean
public Jackson2ObjectMapperBuilderCustomizer personCustomizer()
return jacksonObjectMapperBuilder ->
jacksonObjectMapperBuilder.mixIn(Person.class, PersonMixin.class);
@Bean
public MappingJackson2HttpMessageConverter myMessageConverter(
// provided by Spring
RequestMappingHandlerAdapter reqAdapter,
Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder)
ObjectMapper mapper = jacksonObjectMapperBuilder
.featuresToEnable(SerializationFeature.INDENT_OUTPUT)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.modulesToInstall(new JavaTimeModule())
.build();
// **replace previous MappingJackson converter**
List<HttpMessageConverter<?>> converters =
reqAdapter.getMessageConverters();
converters.removeIf(httpMessageConverter ->
httpMessageConverter.getClass()
.equals(MappingJackson2HttpMessageConverter.class));
MappingJackson2HttpMessageConverter jackson = new
MappingJackson2HttpMessageConverter(mapper);
converters.add(jackson);
reqAdapter.setMessageConverters(converters);
return jackson;
@GetMapping("/test")
public Person get()
return new Person("Mr", "Joe Bloggs");
点击http://localhost:8080/test后在浏览器中输出如下:
"title" : "Mr",
"date" : "2019-09-03",
"fullName" : "Joe Bloggs"
这样,我应该能够根据需要添加尽可能多的定制器。我确信有更好的方法来做到这一点。像这样替换内部组件似乎很hacky...
【讨论】:
感谢这个例子!它很好用,我们无法控制客户端 JDK!以上是关于在 Spring Boot 应用程序中配置 Jackson mixin的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Boot 应用程序中配置 Spring Vault 时出错
如何在 Spring Boot 中配置 Tomcat 关闭端口?
如何在 Spring Boot + Spring Security 应用程序中配置 CORS?
在 Spring Boot 中配置 RequestContextListener