3
votes

I created my RabbitListener to get messages from RabbitMQ queue.

My rabbitMQ message:

Properties  
priority:   0
delivery_mode:  2
headers:    
__TypeId__: com.kmb.bank.models.Transfer
content_encoding:   UTF-8
content_type:   application/json
Payload
356 bytes
Encoding: string


{"userAccountNumber":"1111444422221111","title":"123","recipientName":"123","recipientAccountNumber":"1234123412341234","amount":123.0,"localDateTime":{"nano":526106200,"year":2018,"monthValue":11,"dayOfMonth":29,"hour":20,"minute":43,"second":0,"month":"NOVEMBER","dayOfWeek":"THURSDAY","dayOfYear":333,"chronology":{"id":"ISO","calendarType":"iso8601"}}}

My Listener method:

@Autowired
private Jackson2JsonMessageConverter jackson2JsonMessageConverter;

@RabbitListener(queues = "kolejka")
public void listen(Message message) {
    try {
        Transfer transfer = (Transfer) jackson2JsonMessageConverter.fromMessage(message);
        log.info(transfer);
    } catch (Exception e) {
        log.debug("Error thrown while listening + " + e.getMessage());
    }

}

Bean config: @Bean public ObjectMapper objectMapper() { return new ObjectMapper(); }

@Bean
public Jackson2JsonMessageConverter jackson2JsonMessageConverter() {
    return new Jackson2JsonMessageConverter(objectMapper());
}

And Transfer class:

package com.kmb.transactionlogger.models;

@AllArgsConstructor
public class Transfer {
    @Getter @Setter
    private String userAccountNumber;
    @Getter @Setter
    private String title;
    @Getter @Setter
    private String recipientName;
    @Getter @Setter
    private String recipientAccountNumber;
    @Getter @Setter
    private double amount;
    @Getter @Setter
    private LocalDateTime localDateTime;

}

Unfortunately the exception is being thrown while converting from Message to Transfer transfer object.

Caused by: org.springframework.amqp.support.converter.MessageConversionException: failed to resolve class name. Class not found [com.kmb.bank.models.Transfer]
2018-11-29 20:47:01.615  WARN 13688 --- [cTaskExecutor-1] ingErrorHandler$DefaultExceptionStrategy : Fatal message conversion error; message rejected; it will be dropped or routed to a dead letter exchange, if so configured: (Body:'{"userAccountNumber":"1111444422221111","title":"123","recipientName":"123","recipientAccountNumber":"1234123412341234","amount":123.0,"localDateTime":{"nano":599669800,"year":2018,"monthValue":11,"dayOfMonth":29,"hour":20,"minute":47,"second":1,"month":"NOVEMBER","dayOfWeek":"THURSDAY","dayOfYear":333,"chronology":{"id":"ISO","calendarType":"iso8601"}}}' MessageProperties [headers={__TypeId__=com.kmb.bank.models.Transfer}, contentType=application/json, contentEncoding=UTF-8, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, redelivered=false, receivedExchange=bank, receivedRoutingKey=, deliveryTag=2, consumerTag=amq.ctag-sLNqW-_WhDWLWJk6MCQcjg, consumerQueue=kolejka])

Whole message log: https://pastebin.com/raw/47Lq7dYD

1
Can you provide more detailed log (stacktrace)? - NiVeR
I think it's a problem that it's different Transfer class, package is different from TypeId, but I don't know the solution - Hunteerq
You have to set up the type mapping in the receiving jackson2JsonMessageConverter's type mapper to map to a different class. Alternatively, the framework will infer the type from the parameter if you use public void listen(Transfer transfer) if you wire the converter into the listener container factory. If it's a Boot app, that will happen automatically. - Gary Russell

1 Answers

3
votes

You have to set up the type mapping in the receiving Jackson2JsonMessageConverter's type mapper to map to a different class.

Generally the sender would map its class to a token, e.g. transfer and the receiver will map that to its version of Transfer.

Alternatively, the framework will infer the type from the parameter if you use public void listen(Transfer transfer), and if you wire the converter into the listener container factory.

If it's a Spring Boot application, that wiring will happen automatically.