spring.json.type.mapping 属性 指定自定义 ObjectMapper 时忽略
spring.json.type.mapping property ignored when specifying a custom ObjectMapper
我在将自定义 ObjectMapper
注入 Spring Kafka 序列化程序时遇到问题,我已通过此 answer 解决了问题,LocalDateTime
正在使用正确的模式进行序列化。
@Configuration
public class KafkaCustomizer implements DefaultKafkaProducerFactoryCustomizer {
@Bean
public ObjectMapper objectMapper() {
var mapper = new ObjectMapper();
var module = new JavaTimeModule();
var serializer = new LocalDateTimeSerializer(
DateTimeFormatter.ofPattern(DateConstants.DATETIME_FORMAT_PATTERN));
module.addSerializer(LocalDateTime.class, serializer);
mapper.registerModule(module);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return mapper;
}
@Override
public void customize(DefaultKafkaProducerFactory<?, ?> producerFactory) {
producerFactory.setValueSerializer(new JsonSerializer<>(objectMapper()));
}
}
但现在我遇到了另一个问题,spring.kafka.producer.properties.spring.json.type.mapping
属性 被忽略了。
我的记录的 __TypeId__
header 是用 FQCN 设置的,而不是用我在 spring.json.type.mapping
属性 中输入的令牌设置的:foo > com.foo.package.Foo
当我调试时,org.springframework.kafka.support.serializer.JsonSerializer
class 的 configure
方法似乎没有被调用:
@Override
public void configure(Map<String, ?> configs, boolean isKey) {
...
if (configs.containsKey(TYPE_MAPPINGS) && !this.typeMapperExplicitlySet
&& this.typeMapper instanceof AbstractJavaTypeMapper) {
((AbstractJavaTypeMapper) this.typeMapper)
.setIdClassMapping(createMappings((String) configs.get(TYPE_MAPPINGS)));
}
}
但是当我禁用自定义时
@Override
public void customize(DefaultKafkaProducerFactory<?, ?> producerFactory) {
// producerFactory.setValueSerializer(new JsonSerializer<>(objectMapper()));
}
然后 __TypeId__
header 设置了正确的标记 但是正如预期的那样,我使用自定义 ObjectMapper
松开了日期格式
那么如何处理整个情况?
如果您自己做 new JsonSerializer<>
,您需要自己为它提供适当的生产者配置。当序列化的实例不受Kafka Client控制时,不会调用configure()
。
我会说在你的情况下可以这样做:
public void customize(DefaultKafkaProducerFactory<?, ?> producerFactory) {
JsonSerializer<Object> jsonSerializer = new JsonSerializer<>(objectMapper());
jsonSerializer.configure(producerFactory.getConfigurationProperties(), false);
producerFactory.setValueSerializer(jsonSerializer);
}
文档中有一些信息:https://docs.spring.io/spring-kafka/docs/current/reference/html/#tip-json,但可能我们需要针对编程配置案例扩展它...
我在将自定义 ObjectMapper
注入 Spring Kafka 序列化程序时遇到问题,我已通过此 answer 解决了问题,LocalDateTime
正在使用正确的模式进行序列化。
@Configuration
public class KafkaCustomizer implements DefaultKafkaProducerFactoryCustomizer {
@Bean
public ObjectMapper objectMapper() {
var mapper = new ObjectMapper();
var module = new JavaTimeModule();
var serializer = new LocalDateTimeSerializer(
DateTimeFormatter.ofPattern(DateConstants.DATETIME_FORMAT_PATTERN));
module.addSerializer(LocalDateTime.class, serializer);
mapper.registerModule(module);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return mapper;
}
@Override
public void customize(DefaultKafkaProducerFactory<?, ?> producerFactory) {
producerFactory.setValueSerializer(new JsonSerializer<>(objectMapper()));
}
}
但现在我遇到了另一个问题,spring.kafka.producer.properties.spring.json.type.mapping
属性 被忽略了。
我的记录的 __TypeId__
header 是用 FQCN 设置的,而不是用我在 spring.json.type.mapping
属性 中输入的令牌设置的:foo > com.foo.package.Foo
当我调试时,org.springframework.kafka.support.serializer.JsonSerializer
class 的 configure
方法似乎没有被调用:
@Override
public void configure(Map<String, ?> configs, boolean isKey) {
...
if (configs.containsKey(TYPE_MAPPINGS) && !this.typeMapperExplicitlySet
&& this.typeMapper instanceof AbstractJavaTypeMapper) {
((AbstractJavaTypeMapper) this.typeMapper)
.setIdClassMapping(createMappings((String) configs.get(TYPE_MAPPINGS)));
}
}
但是当我禁用自定义时
@Override
public void customize(DefaultKafkaProducerFactory<?, ?> producerFactory) {
// producerFactory.setValueSerializer(new JsonSerializer<>(objectMapper()));
}
然后 __TypeId__
header 设置了正确的标记 但是正如预期的那样,我使用自定义 ObjectMapper
那么如何处理整个情况?
如果您自己做 new JsonSerializer<>
,您需要自己为它提供适当的生产者配置。当序列化的实例不受Kafka Client控制时,不会调用configure()
。
我会说在你的情况下可以这样做:
public void customize(DefaultKafkaProducerFactory<?, ?> producerFactory) {
JsonSerializer<Object> jsonSerializer = new JsonSerializer<>(objectMapper());
jsonSerializer.configure(producerFactory.getConfigurationProperties(), false);
producerFactory.setValueSerializer(jsonSerializer);
}
文档中有一些信息:https://docs.spring.io/spring-kafka/docs/current/reference/html/#tip-json,但可能我们需要针对编程配置案例扩展它...