Как заставить Spring Kafka JsonDeserializer сохранять смещение часового пояса при десериализации в OffsetDateTime
У меня есть сообщение, полученное через Kafka, в котором, как я знаю, указан часовой пояс, отличный от UTC. Когда я использую
org.apache.kafka.common.serialization.StringDeserializer
чтобы проверить это, я получаю правильную временную метку в формате ISO 8601 с часовым поясом:
{ "id": "e499f2e8-a50e-4ff8-a9fe-0eaf9d3314bf", "sent_ts": "2021-02-04T14:06:10+01:00" }
Когда я переключаюсь на
org.springframework.kafka.support.serializer.JsonDeserializer
это потеряно. Мой 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 +
'}';
}
Когда я регистрирую полученное сообщение, я получаю:
MyMessage{id='e499f2e8-a50e-4ff8-a9fe-0eaf9d3314bf', sentTs=2021-02-04T13:06:10Z}
Я думал, что, должно быть, использовал Джексона, поэтому в моем
application.yml
конфигурацию я установил:
spring.jackson:
deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE: false
Это не сработало. Еще попробовал настроить настройщик:
@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);
}
}
Что тоже не сработало.
Я подумал, может быть, это должно быть свойство потребителя 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
По-прежнему не работает.
Есть ли способ сделать
JsonDeserializer
работать правильно и сохранять правильное смещение часового пояса?
1 ответ
Когда тебе это нравится
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
, экземпляр этого класса создается клиентским кодом Apache Kafka, который полностью не знает конфигурации Spring.
Если вы хотите полагаться на настройки Spring Boot и свои настройки, вам следует подумать о том, чтобы сделать что-то вроде этого:
@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);
}
Обратите внимание, как я звоню
jsonDeserializer.configure(consumerProperties, false);
. Таким образом, вы по-прежнему сможете настроить остальные свойства для потребителя Kafka в
applicaiton.yml
.
Пожалуйста, подумайте о том, чтобы поднять проблему GH для Spring Boot, поэтому мы пересмотрим, как мы будем работать с
JsonDeserializer
и автоматически настраивается
ObjectMapper
для улучшения взаимодействия с конечным пользователем на сервере.