Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Given I have IntegrationFlow and inbound adapter for AMQP queue:

@Bean
public IntegrationFlow readMessagesFlow(
        ConnectionFactory rabbitConnectionFactory,
        ObjectMapper jacksonObjectMapper) {
    return IntegrationFlows.from(
            Amqp.inboundAdapter(rabbitConnectionFactory, QUEUE)
                    .messageConverter(new Jackson2JsonMessageConverter(jacksonObjectMapper))
            .log(INFO, AMQP_LOGGER_CATEGORY)
            .get();

When some external system sends a message with JSON body, I found they use __TypeId__=THEIR_INTERNAL_CLASS.

I would like to map JSON body to my own class.

Currently, it fails on ClassCastException because of THEIR_INTERNAL_CLASS not being available.

How can I tell Jackson2JsonMessageConverter to use my own class?

This is one way how to do it:

Jackson2JsonMessageConverter messageConverter = new Jackson2JsonMessageConverter(jacksonObjectMapper);
DefaultClassMapper defaultClassMapper = new DefaultClassMapper();
defaultClassMapper.setDefaultType(MyOwnClass.class);
messageConverter.setClassMapper(defaultClassMapper);

and use messageConverter in Amqp.inboundAdapter

See this method of converter:

* Set the precedence for evaluating type information in message properties. * When using {@code @RabbitListener} at the method level, the framework attempts * to determine the target type for payload conversion from the method signature. * If so, this type is provided in the * {@link MessageProperties#getInferredArgumentType() inferredArgumentType} * message property. * <p> By default, if the type is concrete (not abstract, not an interface), this will * be used ahead of type information provided in the {@code __TypeId__} and * associated headers provided by the sender. * <p> If you wish to force the use of the {@code __TypeId__} and associated headers * (such as when the actual type is a subclass of the method argument type), * set the precedence to {@link Jackson2JavaTypeMapper.TypePrecedence#TYPE_ID}. * @param typePrecedence the precedence. * @see DefaultJackson2JavaTypeMapper#setTypePrecedence(Jackson2JavaTypeMapper.TypePrecedence) public void setTypePrecedence(Jackson2JavaTypeMapper.TypePrecedence typePrecedence) {

and here are docs on the matter: https://docs.spring.io/spring-amqp/docs/2.2.11.RELEASE/reference/html/#json-message-converter

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.