如何覆盖 Spring Cloud Stream 的 Jackson ObjectMapper 配置?

How to override Jackson ObjectMapper configuration for Spring Cloud Stream?

在 Spring Boot/Spring Cloud Stream 应用程序中,我们使用的是 Kafka 活页夹。我注意到,在反序列化包含 ZonedDateTime 属性 的 Kafka 消息时,Jackson 会自动更改时区(到 UTC),即使序列化形式包含时区(例如,20210101084239+0200 ). 经过一些研究,我发现这是一个可以禁用的默认反序列化功能,因此我在 @Configuration 类:

之一中添加了以下内容
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer objectMapperCustomizer() {
        return builder ->  {
            builder.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
            //... other custom config...
        };

但这不起作用,大概是因为 Spring Cloud Stream(或 Kafka 绑定程序)使用的 ObjectMapper 不是从应用程序上下文中配置的 Jackson2ObjectMapperBuilder 构建的:-( .

经过更多研究,我发现有人声称有必要覆盖 Spring 消息的 MappingJackson2MessageConverter,因为它创建了自己的 ObjectMapper。所以我添加了这个:

    @Bean
    public MappingJackson2MessageConverter springMessagingJacksonConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.getObjectMapper().configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);

        return converter;
    }

不幸的是,这仍然没有用。我仍然在忽略 JSON 值中的时区信息而反序列化 ZonedDateTime 个对象。

那么什么 bean 创建了 Spring Cloud Stream Kafka binder 使用的 ObjectMapper,我如何自定义它的配置?

请参阅spring boot reference

If you want to replace the default ObjectMapper completely, either define a @Bean of that type and mark it as @Primary or, if you prefer the builder-based approach, define a Jackson2ObjectMapperBuilder @Bean. Note that, in either case, doing so disables all auto-configuration of the ObjectMapper.

如以下讨论评论和 here 中所述,Spring Cloud Stream 中存在一个错误,它没有使用 Spring 应用程序上下文中的 ObjectMapper它应该的地方。

话虽如此,解决方法是定义您自己的 Serde<> @Bean,它调用采用 ObjectMapperJsonSerde<> 构造函数,后者是从应用程序上下文中注入的。例如:

@Configuration
public class MyConfig {
    @Bean
    public Serde<SomeClass> someClassSerde(ObjectMapper jsonMapper) {
        return new JsonSerde<SomeClass>(SomeClass.class, jsonMapper);
    }
}

此解决方法的不利之处在于,您必须对要在消息中 serialize/deserialize 的每个目标类型执行此操作。