I have a message being received through Kafka, which I know has a non-UTC timezone in it.
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:
{ "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. My POJO looks like this:
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:
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:
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?
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.If you'd like to rely on the
ObjectMapperconfigured by Spring Boot and your customizations, you should consider to do something like this:Pay attention how I call
jsonDeserializer.configure(consumerProperties, false);. This way you still will be able to configure the rest of properties for Kafka consumer in theapplicaiton.yml.Please, consider to raise GH issue for Spring Boot, so we will revise how we deal with
JsonDeserializerand auto-configuredObjectMapperto server better end-user experience.