Spring-引导:不遵守 Jackson 序列化配置
Spring-Boot: Jackson serialization configuration not respected
我正在使用 spring-boot 2.5.4 并尝试全局设置 default-property-inclusion=non_null
,以便空值不再出现在我的 spring 网络服务器的响应中。
我已按照 .
中所述在项目的 application.yml
中配置 spring.jackson.default-property-inclusion=non_null
spring:
jackson:
default-property-inclusion: non_null
不幸的是,空值仍然包含在我的控制器的输出中:
{
"enabled": true,
"name": "foo",
"subdomain": null,
"tenantId": null
}
然而,如果我将非空值直接添加到我的 dto 中,则有效:
@Data
@NoArgsConstructor
@JsonInclude(Include.NON_NULL)
public class GlobalTenantGet {
private UUID tenantId;
private String name;
private String subdomain;
private boolean enabled;
}
屈服
{
"enabled": true,
"name": "foo"
}
符合预期。
问题
为什么在 dto 上本地配置 @JsonInclude
会导致 null 属性按预期消失,但为什么配置 spring.jackson.default-property-inclusion=non_null
却没有相同的效果?
附加信息
1。调试
在 org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper
中设置断点表明,在 application.yaml
中配置的属性确实到达了 jackson:
2。在控制器
中自动装配ObjectMapper
在我的控制器中自动装配 ObjectMapper
并直接通过 objectMapper.writeValueAsString()
序列化我的对象时,我得到了预期的行为。
其他配置方式ObjectMapper
这些主要是回复的回答
1。使用@primary
我有一个
@Configuration
public class ObjectMapperConfiguration {
@Primary
@Bean
public ObjectMapper objectMapper() {
final var om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_NULL);
return om;
}
}
输出中仍然包含空属性
2。 Jackson2ObjectMapperBuilder
与 serializationInclusion
@Configuration
public class ObjectMapperConfiguration {
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return new Jackson2ObjectMapperBuilder().serializationInclusion(JsonInclude.Include.NON_NULL);
}
}
仍然产量
{
"enabled": true,
"name": "foo",
"subdomain": null,
"tenantId": null
}
3。定义 MappingJackson2HttpMessageConverter
@Configuration
public class ObjectMapperConfiguration {
@Bean
public MappingJackson2HttpMessageConverter messageMappingConverter() {
final var om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_NULL);
return new MappingJackson2HttpMessageConverter(om);
}
}
仍然没有布埃诺:-(
有几种可能的方法可以解决这个问题,其中一些在此处有明确的解释:https://www.baeldung.com/spring-boot-customize-jackson-objectmapper
通常你可以:
通过创建自定义 ObjectMapper
bean 并将其标记为 @Primary
来覆盖默认值 ObjectMapper
(最简单的方法,但会严重影响您的应用程序,因为所有 ObjectMapper
你在代码中注入的实例将默认使用这个,这对你来说可能是好是坏)
为 Jackson2ObjectMapperBuilder
定义自定义 bean 并在此构建器上设置适当的 serializationInclusion
。
在 Spring 中注册自定义 HTTP 消息转换器,它将通过为 MappingJackson2HttpMessageConverter
定义 bean 使用自定义 ObjectMapper(此转换器的构造函数接受 ObjectMapper
,因此您可以通过在那里正确配置映射器)
看来 @EnableWebMvc
是罪魁祸首。我有一个看起来像这样的 WebMvcConfigurer
:
@Configuration
@EnableWebMvc // <----- this is the culprit!
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
.allowedOrigins("example.com")
.allowedHeaders("*");
}
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
public InternalResourceViewResolver defaultViewResolver() {
return new InternalResourceViewResolver();
}
}
注释掉 @EnableWebMvc
允许一切按预期工作。
我正在使用 spring-boot 2.5.4 并尝试全局设置 default-property-inclusion=non_null
,以便空值不再出现在我的 spring 网络服务器的响应中。
我已按照
application.yml
中配置 spring.jackson.default-property-inclusion=non_null
spring:
jackson:
default-property-inclusion: non_null
不幸的是,空值仍然包含在我的控制器的输出中:
{
"enabled": true,
"name": "foo",
"subdomain": null,
"tenantId": null
}
然而,如果我将非空值直接添加到我的 dto 中,则有效:
@Data
@NoArgsConstructor
@JsonInclude(Include.NON_NULL)
public class GlobalTenantGet {
private UUID tenantId;
private String name;
private String subdomain;
private boolean enabled;
}
屈服
{
"enabled": true,
"name": "foo"
}
符合预期。
问题
为什么在 dto 上本地配置 @JsonInclude
会导致 null 属性按预期消失,但为什么配置 spring.jackson.default-property-inclusion=non_null
却没有相同的效果?
附加信息
1。调试
在 org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper
中设置断点表明,在 application.yaml
中配置的属性确实到达了 jackson:
2。在控制器
中自动装配ObjectMapper
在我的控制器中自动装配 ObjectMapper
并直接通过 objectMapper.writeValueAsString()
序列化我的对象时,我得到了预期的行为。
其他配置方式ObjectMapper
这些主要是回复
1。使用@primary
我有一个
@Configuration
public class ObjectMapperConfiguration {
@Primary
@Bean
public ObjectMapper objectMapper() {
final var om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_NULL);
return om;
}
}
输出中仍然包含空属性
2。 Jackson2ObjectMapperBuilder
与 serializationInclusion
@Configuration
public class ObjectMapperConfiguration {
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return new Jackson2ObjectMapperBuilder().serializationInclusion(JsonInclude.Include.NON_NULL);
}
}
仍然产量
{
"enabled": true,
"name": "foo",
"subdomain": null,
"tenantId": null
}
3。定义 MappingJackson2HttpMessageConverter
@Configuration
public class ObjectMapperConfiguration {
@Bean
public MappingJackson2HttpMessageConverter messageMappingConverter() {
final var om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_NULL);
return new MappingJackson2HttpMessageConverter(om);
}
}
仍然没有布埃诺:-(
有几种可能的方法可以解决这个问题,其中一些在此处有明确的解释:https://www.baeldung.com/spring-boot-customize-jackson-objectmapper
通常你可以:
通过创建自定义
ObjectMapper
bean 并将其标记为@Primary
来覆盖默认值ObjectMapper
(最简单的方法,但会严重影响您的应用程序,因为所有ObjectMapper
你在代码中注入的实例将默认使用这个,这对你来说可能是好是坏)为
Jackson2ObjectMapperBuilder
定义自定义 bean 并在此构建器上设置适当的serializationInclusion
。在 Spring 中注册自定义 HTTP 消息转换器,它将通过为
MappingJackson2HttpMessageConverter
定义 bean 使用自定义 ObjectMapper(此转换器的构造函数接受ObjectMapper
,因此您可以通过在那里正确配置映射器)
看来 @EnableWebMvc
是罪魁祸首。我有一个看起来像这样的 WebMvcConfigurer
:
@Configuration
@EnableWebMvc // <----- this is the culprit!
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
.allowedOrigins("example.com")
.allowedHeaders("*");
}
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
public InternalResourceViewResolver defaultViewResolver() {
return new InternalResourceViewResolver();
}
}
注释掉 @EnableWebMvc
允许一切按预期工作。