Tell Jackson2JsonMessageConverter to use my own class in Amqp.inboundAdapter

1.3k views Asked by At

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?

2

There are 2 answers

0
Patrik Mihalčin On

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

0
Artem Bilan On

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