简体   繁体   English

如何使 Spring Kafka JsonDeserializer 在反序列化为 OffsetDateTime 时保留时区偏移

[英]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.

相关问题 如何在使用Jackson反序列化OffsetDateTime时保留偏移量 - How to preserve the offset while deserializing OffsetDateTime with Jackson 如何在 Spring Kafka 中以编程方式设置 JsonDeserializer TypeValue 方法 - How to I programaticaly set JsonDeserializer TypeValue method in Spring Kafka Spring Boot 将 ObjectMapper 注入 Kafka JsonDeserializer - Spring Boot inject ObjectMapper into Kafka JsonDeserializer spring Kafka 集成测试侦听器不工作(KAFKA JsonDeserializer) - spring Kafka integration test listener not working (KAFKA JsonDeserializer) 您如何禁用受信任的.packages 检查 Spring-Kafka JsonDeserializer? - How do you disable trusted.packages check for Spring-Kafka JsonDeserializer? 如何从春季要求中获取时区偏移量? - How get timezone offset from spring request? 如何在 Spring Kafka 客户端中寻找偏移量? - How to seek to the offset in Spring Kafka client? 如何为Kafka用Spring寻找时间戳的偏移 - How to seek Offset for Time Stamp with Spring for Kafka Spring Kafka 偏移管理 - Spring Kafka offset management 如何从给定的 OffsetDatetime 获取 LocalDate(yyyy-MM-dd) 格式并返回为 OffsetDatetime 而没有区域偏移? - How to get LocalDate(yyyy-MM-dd) format from given OffsetDatetime and return as OffsetDatetime without zone offset?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM