-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Currently it is very cumbersome to configure the ObjectMapper of the JsonDeserializer. One would incorrectly assume that the ObjectMapper configuration set through application.yaml such as the following would work:
spring.jackson:
deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE: false
But it doesn't, for some reason the JsonDeserializer uses its own ObjectMapper ignoring the one configured in the rest of the application. More details seem to be here #680
The only alternative here, as indicated in the documentation, is to define your own JsonDeserializer bean, like this:
@Bean
Deserializer jsonDeserializer(ObjectMapper objectMapper) {
return new JsonDeserializer(objectMapper);
}
However this means that the configuration passed through the application.yaml for JsonDeserializer is now lost.
After lots of searching and seeking help here: https://stackoverflow.com/questions/66061869/how-to-make-spring-kafka-jsondeserializer-retain-the-timezone-offset-when-deseri/
thanks to @artembilan the only solution to this is to do something like the following:
@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);
}
For some reason the following typesafe way does not work either, which makes things even more confusing:
@Bean
ConsumerFactory<String, Object> kafkaConsumerFactory(
KafkaProperties properties, ObjectMapper objectMapper) {
Map<String, Object> configs = properties.buildConsumerProperties();
JsonDeserializer<Object> jsonDeserializer = new JsonDeserializer<>(objectMapper);
jsonDeserializer.configure(configs, false);
return new DefaultKafkaConsumerFactory<>(
properties.buildConsumerProperties(), new StringDeserializer(), jsonDeserializer);
}
This is not intuitive at all, and difficult to come up with on your own without knowing the internals (apart from the ugly Object generic type).
If it is not possible to use the same ObjectMapper used in the spring context, maybe the right properties for the ObjectMapper can be passed through the spring.kafka.consumer.properties just like the spring.json.value.default.type.