如何在 Spring-AMQP 中使用 Jackson2JsonMessageConverter 处理内容类型 null

How do I handle content-type null with Jackson2JsonMessageConverter in Spring-AMQP

如果 it's not one problem, ... 我似乎已经解决了之前的 2 个问题,但现在当 运行 在测试上下文之外时,我看到了一个站立的应用程序。

o.s.a.s.c.Jackson2JsonMessageConverter   : Could not convert incoming message with content-type [null], 'json' keyword missing.

和以前一样,这条消息看起来很清楚。哎呀,事情甚至在独立测试上下文中工作,但是当 运行 在独立服务器中时,代码似乎采用了不同的路径并且由于相同的原因失败,但通过不同的组件。

@Configuration
open class MessagingConfig {

    @Bean
    open fun jackson2Json(om: ObjectMapper): SmartMessageConverter {
        return Jackson2JsonMessageConverter(om)
    }

    @Bean
    open fun mappingJackson2(om: ObjectMapper): MappingJackson2MessageConverter {
        val mc = MappingJackson2MessageConverter()
        mc.objectMapper = om
        return mc
    }

    @Bean
    open fun defaultMessageHandlerMethodFactory(jackson: MappingJackson2MessageConverter): DefaultMessageHandlerMethodFactory {
        val factory = DefaultMessageHandlerMethodFactory()
        factory.setMessageConverter(jackson)
        return factory
    }


    @Bean
    open fun builder(): Jackson2ObjectMapperBuilderCustomizer {
        return Jackson2ObjectMapperBuilderCustomizer {
            it.modules(JavaTimeModule(), KotlinModule())
            it.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
        }
    }


    @Configuration
    open class RabbitConfigurer(val dmhmf: DefaultMessageHandlerMethodFactory) : RabbitListenerConfigurer {
        override fun configureRabbitListeners(registrar: RabbitListenerEndpointRegistrar?) {
            registrar?.messageHandlerMethodFactory = dmhmf
        }
    }
}

根据AbstractJackson2MessageConverter中的逻辑,需要contentType AMQP 属性:

MessageProperties properties = message.getMessageProperties();
    if (properties != null) {
        String contentType = properties.getContentType();
        if (contentType != null && contentType.contains(this.supportedContentType.getSubtype())) {

我认为我们需要对此组件进行改进,不要对它严格要求。与我们可以通过其对 MappingJackson2MessageConverter 执行的操作相同:

/**
 * Whether this converter should convert messages for which no content type
 * could be resolved through the configured
 * {@link org.springframework.messaging.converter.ContentTypeResolver}.
 * <p>A converter can configured to be strict only when a
 * {@link #setContentTypeResolver contentTypeResolver} is configured and the
 * list of {@link #getSupportedMimeTypes() supportedMimeTypes} is not be empty.
 * <p>When this flag is set to {@code true}, {@link #supportsMimeType(MessageHeaders)}
 * will return {@code false} if the {@link #setContentTypeResolver contentTypeResolver}
 * is not defined or if no content-type header is present.
 */
public void setStrictContentTypeMatch(boolean strictContentTypeMatch) {

默认为 false

只有解决遗漏 contentType 问题的方法,但仍继续进行 JSON 消息转换,我看到自定义 org.springframework.amqp.support.converter.AbstractMessageConverter 实现,您可以在其中组合 Jackson2JsonMessageConverter逻辑和不关心错过contentType属性.

随时针对 Spring AMQP 提出问题以改进 AbstractJackson2MessageConverter

您可以将 MessagePostprocessor 添加到容器工厂以使用 content_id 属性 增强消息。

factory.setAfterReceivePostProcessors(m -> {
    m.getMessageProperties().setContentId("application/json");
    return m;
}