无法将 Message 对象从 RabbitMQ 转换为 java class
Can't convert Message object from RabbitMQ to java class
我创建了 RabbitListener 以从 RabbitMQ 队列获取消息。
我的rabbitMQ消息:
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"}}}
我的监听器方法:
@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 配置:
@豆
public ObjectMapper objectMapper() {
return 新对象映射器();
}
@Bean
public Jackson2JsonMessageConverter jackson2JsonMessageConverter() {
return new Jackson2JsonMessageConverter(objectMapper());
}
并转移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;
}
不幸的是,从 Message 转换为 Transfer 传输对象时抛出异常。
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])
您必须在接收 Jackson2JsonMessageConverter
的类型映射器中设置类型映射以映射到不同的 class。
一般情况下,发件人会将其 class 映射到令牌,例如transfer
并且接收方会将其映射到它的 Transfer
.
版本
或者,如果您使用 public void listen(Transfer transfer)
,并且您将转换器连接到侦听器容器工厂,则框架将从参数推断类型。
如果它是 Spring 引导应用程序,该连接将自动发生。
我遇到了这个问题,当我尝试使用自定义消息转换器时,有些人会在尝试解析 spring 生产者在 header 上指定的 class 时抛出错误。我最终使用 ObjectMapper
class.
将 object class 转换为 json 字符串
我想指出的一件事是,这样做会将内容作为字符串化 JSON
发送到 Rabbit MQ。因此,您可以在消费者 class 上将其作为字符串接收,使用 objectMapper.read(stringType, mappedToClass)
.
将其映射到另一个自定义 class
我得到的另一个好处是我可以直接在其他用python
或nodejs
写的消费者中读取它
总结
在spring开机发送时,
rabbitTemplate.convertAndSend(exchange, key, objectMapper.writeValueAsString())
.
在 spring 引导用户读取自定义 object 时不必
匹配消费者 object.
CustomObj obj = objectMapper.read(incomingString, CustomObj.class)
.
A point to note is that, make sure to ignoreUnknown
fields in the custom object class,
我创建了 RabbitListener 以从 RabbitMQ 队列获取消息。
我的rabbitMQ消息:
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"}}}
我的监听器方法:
@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 配置: @豆 public ObjectMapper objectMapper() { return 新对象映射器(); }
@Bean
public Jackson2JsonMessageConverter jackson2JsonMessageConverter() {
return new Jackson2JsonMessageConverter(objectMapper());
}
并转移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;
}
不幸的是,从 Message 转换为 Transfer 传输对象时抛出异常。
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])
您必须在接收 Jackson2JsonMessageConverter
的类型映射器中设置类型映射以映射到不同的 class。
一般情况下,发件人会将其 class 映射到令牌,例如transfer
并且接收方会将其映射到它的 Transfer
.
或者,如果您使用 public void listen(Transfer transfer)
,并且您将转换器连接到侦听器容器工厂,则框架将从参数推断类型。
如果它是 Spring 引导应用程序,该连接将自动发生。
我遇到了这个问题,当我尝试使用自定义消息转换器时,有些人会在尝试解析 spring 生产者在 header 上指定的 class 时抛出错误。我最终使用 ObjectMapper
class.
我想指出的一件事是,这样做会将内容作为字符串化 JSON
发送到 Rabbit MQ。因此,您可以在消费者 class 上将其作为字符串接收,使用 objectMapper.read(stringType, mappedToClass)
.
我得到的另一个好处是我可以直接在其他用python
或nodejs
总结
在spring开机发送时,
rabbitTemplate.convertAndSend(exchange, key, objectMapper.writeValueAsString())
.
在 spring 引导用户读取自定义 object 时不必
匹配消费者 object.
CustomObj obj = objectMapper.read(incomingString, CustomObj.class)
.
A point to note is that, make sure to
ignoreUnknown
fields in the custom object class,