ObjectMapper 启用方法已弃用
ObjectMapper enable method is deprecated
我正在升级我的项目版本,我目前使用的是 jackson-databind-2.13.0
.但我注意到 ObjectMapper 的 enable 方法已被弃用。
他们说要这样用。
@deprecated Since 2.13 use {@code JsonMapper.builder().enable(...)}
但是我无法使用它。
下面是我的 ObjectMapper 实例创建代码。我该如何改变?
@Bean(name = {"objectMapper"})
@Primary
ObjectMapper objectMapper() {
return newObjectMapper();
}
public static ObjectMapper newObjectMapper() {
ObjectMapper objectMapper =
new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer());
javaTimeModule.addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer());
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer());
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
objectMapper
.registerModule(javaTimeModule)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return objectMapper;
}
解决方案:
ObjectMapper objectMapper = JsonMapper
.builder()
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.serializationInclusion(Include.NON_NULL).build();
我建议将您的代码重写为
- 删除此 bean 并使用完全 Spring 配置的引导
ObjectMapper
(名称为 jacksonObjectMapper
)
- 使用
Jackson2ObjectMapperBuilder
创建 ObjectMapper
的实例。
所有这些解决方案都隐藏了构建 ObjectMapper
的复杂部分,并且还将(正确地)构建它的负担交给 Spring 引导团队,而不是你。
现在,对于选项 1,您需要删除 @Bean
并将以下内容放入 application.properties
。
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=false
spring.jackson.deserialization.ACCEPT_SINGLE_VALUE_AS_ARRAY=true
spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=true
spring.jackson.defaultPropertyInclusion=NON_NULL
当 Spring(引导)在类路径上检测到 JavaTime
模块时,它将自动注册到 ObjectMapper
,因此无需额外添加(或序列化程序)那很重要)。
这些配置行应该与您明确配置的配置相同 ObjectMapper
。 H
对于第二个选项,您可以使用参数将 Jackson2ObjectMapperBuilder
注入方法,在那里配置您想要的东西,最后调用 build
方法。
@Bean(name = {"objectMapper"})
@Primary
ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
return newObjectMapper(builder);
}
public static ObjectMapper newObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder
.serializationInclusion(NON_NULL)
.failOnEmptyBeans(false)
.failOnUnknownProperties(false)
.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.build();
您仍然不需要注册 JavaTime
模块,因为它仍在为您自动检测。
理论上您可以将 1 和 2 结合起来,但在您的情况下不会增加太多,只需一些代码来构造 ObjectMapper
。
@Bean(name = {"objectMapper"})
@Primary
ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
return newObjectMapper(builder);
}
public static ObjectMapper newObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.build();
}
我在尝试通过 MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS
启用 Enum 不区分大小写的反序列化时遇到了类似的问题。
在我的例子中,由于 ObjectMapper
之前是由外部源构建的,因此无法切换到构建器方法。所以唯一的选择是直接修改 ObjectMapper
反序列化配置。
寻找替代方案以避免弃用 API objectMapper.enable(MappedFeature... f)
我找到了一个解决方法...
- 从
ObjectMapper
实例获取原始 DeserializationConfig
。
- 正在创建 'copy' 原始配置
MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS
通过调用启用
with(MapperFeature... features)
在配置的实例上。
- 用新配置替换
ObjectMapper
原来的配置
setter 方法。
这也适用于 SerializationConfig
,它是一种在不使用已弃用的 API 的情况下修改已构建的 ObjectMapper
配置的方法。
public void customizeMapper(ObjectMapper objectMapper) {
final DeserializationConfig originalConfig = objectMapper.getDeserializationConfig();
final DeserializationConfig newConfig = originalConfig.with(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);
objectMapper.setConfig(newConfig);
}
注意:使用Jackson的builder绝对是更好的解决方案。仅当无法使用生成器时才考虑此方法。
我正在升级我的项目版本,我目前使用的是 jackson-databind-2.13.0 .但我注意到 ObjectMapper 的 enable 方法已被弃用。
他们说要这样用。
@deprecated Since 2.13 use {@code JsonMapper.builder().enable(...)}
但是我无法使用它。
下面是我的 ObjectMapper 实例创建代码。我该如何改变?
@Bean(name = {"objectMapper"})
@Primary
ObjectMapper objectMapper() {
return newObjectMapper();
}
public static ObjectMapper newObjectMapper() {
ObjectMapper objectMapper =
new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer());
javaTimeModule.addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer());
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer());
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
objectMapper
.registerModule(javaTimeModule)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return objectMapper;
}
解决方案:
ObjectMapper objectMapper = JsonMapper
.builder()
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.serializationInclusion(Include.NON_NULL).build();
我建议将您的代码重写为
- 删除此 bean 并使用完全 Spring 配置的引导
ObjectMapper
(名称为jacksonObjectMapper
) - 使用
Jackson2ObjectMapperBuilder
创建ObjectMapper
的实例。
所有这些解决方案都隐藏了构建 ObjectMapper
的复杂部分,并且还将(正确地)构建它的负担交给 Spring 引导团队,而不是你。
现在,对于选项 1,您需要删除 @Bean
并将以下内容放入 application.properties
。
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=false
spring.jackson.deserialization.ACCEPT_SINGLE_VALUE_AS_ARRAY=true
spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_PROPERTIES=true
spring.jackson.defaultPropertyInclusion=NON_NULL
当 Spring(引导)在类路径上检测到 JavaTime
模块时,它将自动注册到 ObjectMapper
,因此无需额外添加(或序列化程序)那很重要)。
这些配置行应该与您明确配置的配置相同 ObjectMapper
。 H
对于第二个选项,您可以使用参数将 Jackson2ObjectMapperBuilder
注入方法,在那里配置您想要的东西,最后调用 build
方法。
@Bean(name = {"objectMapper"})
@Primary
ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
return newObjectMapper(builder);
}
public static ObjectMapper newObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder
.serializationInclusion(NON_NULL)
.failOnEmptyBeans(false)
.failOnUnknownProperties(false)
.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.build();
您仍然不需要注册 JavaTime
模块,因为它仍在为您自动检测。
理论上您可以将 1 和 2 结合起来,但在您的情况下不会增加太多,只需一些代码来构造 ObjectMapper
。
@Bean(name = {"objectMapper"})
@Primary
ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
return newObjectMapper(builder);
}
public static ObjectMapper newObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.build();
}
我在尝试通过 MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS
启用 Enum 不区分大小写的反序列化时遇到了类似的问题。
在我的例子中,由于 ObjectMapper
之前是由外部源构建的,因此无法切换到构建器方法。所以唯一的选择是直接修改 ObjectMapper
反序列化配置。
寻找替代方案以避免弃用 API objectMapper.enable(MappedFeature... f)
我找到了一个解决方法...
- 从
ObjectMapper
实例获取原始DeserializationConfig
。 - 正在创建 'copy' 原始配置
MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS
通过调用启用with(MapperFeature... features)
在配置的实例上。 - 用新配置替换
ObjectMapper
原来的配置 setter 方法。
这也适用于 SerializationConfig
,它是一种在不使用已弃用的 API 的情况下修改已构建的 ObjectMapper
配置的方法。
public void customizeMapper(ObjectMapper objectMapper) {
final DeserializationConfig originalConfig = objectMapper.getDeserializationConfig();
final DeserializationConfig newConfig = originalConfig.with(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);
objectMapper.setConfig(newConfig);
}
注意:使用Jackson的builder绝对是更好的解决方案。仅当无法使用生成器时才考虑此方法。