Search code examples
javaspringkotlinspring-amqp

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


If it's not one problem, it's another... I seem to have gotten the 2 previous problems fixed but now when running outside of a test context, with a stood up application I see this.

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

Like before, this message seems fairly clear. Heck, things even worked in a standalone test context, however when running in a standalone server the code seems to be taking a different path and is failing for the same reason but via a different component.

@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
        }
    }
}

Solution

  • You can add a MessagePostprocessor to the container factory to enhance the message with a content_id property.

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