[英]How to make Spring Kafka JsonDeserializer retain the timezone offset when deserializing to OffsetDateTime
I have a message being received through Kafka, which I know has a non-UTC timezone in it.我通过 Kafka 收到一条消息,我知道其中有一个非 UTC 时区。 When I use the org.apache.kafka.common.serialization.StringDeserializer
to verify this I get the right timestamp in ISO 8601 format with the timezone:当我使用org.apache.kafka.common.serialization.StringDeserializer
来验证这一点时,我得到了带有时区的 ISO 8601 格式的正确时间戳:
{ "id": "e499f2e8-a50e-4ff8-a9fe-0eaf9d3314bf", "sent_ts": "2021-02-04T14:06:10+01:00" }
When I switch to the org.springframework.kafka.support.serializer.JsonDeserializer
this is lost.当我切换到org.springframework.kafka.support.serializer.JsonDeserializer
这丢失了。 My POJO looks like this:我的 POJO 看起来像这样:
public class MyMessage {
@JsonProperty("id")
private String id;
@JsonProperty("sent_ts")
private OffsetDateTime sentTs;
@Override
public String toString() {
return "MyMessage{" +
"id='" + id + '\'' +
", sentTs=" + sentTs +
'}';
}
When I log the message I receive I get:当我记录收到的消息时,我得到:
MyMessage{id='e499f2e8-a50e-4ff8-a9fe-0eaf9d3314bf', sentTs=2021-02-04T13:06:10Z}
I thought the JsonDeserializer
must be using Jackson so in my application.yml
configuration I set:我认为JsonDeserializer
必须使用 Jackson 所以在我的application.yml
配置中我设置:
spring.jackson:
deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE: false
This didn't work.这没有用。 I also tried to a customizer:我还尝试了定制器:
@Configuration
public class ObjectMapperBuilderCustomizer implements Jackson2ObjectMapperBuilderCustomizer {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.modules(new JavaTimeModule());
builder.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
}
}
Which didn't work either.这也不起作用。
I though maybe it needs to be a property of the Kafka consumer, so I also tried:我虽然可能它需要成为 Kafka 消费者的属性,所以我也尝试了:
spring:
consumer:
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring.jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE: false
Still doesn't work.还是不行。
Is there a way to make the JsonDeserializer
work properly and keep the correct timezone offset?有没有办法让JsonDeserializer
正常工作并保持正确的时区偏移?
When you do like this value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
, the instance of that class is created by Apache Kafka client code which is fully not aware of Spring configuration.当您喜欢这个value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
,该 class 的实例是由 Apache Kafka 客户端代码创建的,该代码完全不知道 Z380108FECDD810CE28
If you'd like to rely on the ObjectMapper
configured by Spring Boot and your customizations, you should consider to do something like this:如果您想依赖 Spring Boot 配置的ObjectMapper
和您的自定义,您应该考虑执行以下操作:
@Bean
DefaultKafkaConsumerFactory kafkaConsumerFactory(KafkaProperties properties, ObjectMapper objectMapper) {
Map<String, Object> consumerProperties = properties.buildConsumerProperties();
JsonDeserializer<Object> jsonDeserializer = new JsonDeserializer<>(objectMapper);
jsonDeserializer.configure(consumerProperties, false);
return new DefaultKafkaConsumerFactory(consumerProperties,
new StringDeserializer(), jsonDeserializer);
}
Pay attention how I call jsonDeserializer.configure(consumerProperties, false);
注意我如何调用jsonDeserializer.configure(consumerProperties, false);
. . This way you still will be able to configure the rest of properties for Kafka consumer in the applicaiton.yml
.这样,您仍然可以在 applicaiton.yml 中为 Kafka 消费者配置applicaiton.yml
属性。
Please, consider to raise GH issue for Spring Boot, so we will revise how we deal with JsonDeserializer
and auto-configured ObjectMapper
to server better end-user experience.请考虑为 Spring Boot 提出 GH 问题,因此我们将修改处理JsonDeserializer
和自动配置ObjectMapper
的方式,以提供更好的最终用户体验。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.