从RabbitMQ中收到的Byte []消息转换为基于模型的对象时,我遇到了问题。
我正在使用Spring Boot。
在应用程序中,我实现了RabbitListenerConfigurer
:
@SpringBootApplication
class Application : RabbitListenerConfigurer {
...
override fun configureRabbitListeners(registrar: RabbitListenerEndpointRegistrar) {
registrar.messageHandlerMethodFactory = messageHandlerMethodFactory()
}
@Bean
fun messageHandlerMethodFactory(): MessageHandlerMethodFactory {
val messageHandlerMethodFactory = DefaultMessageHandlerMethodFactory()
messageHandlerMethodFactory.setMessageConverter(consumerJackson2MessageConverter())
return messageHandlerMethodFactory
}
@Bean
fun consumerJackson2MessageConverter(): MappingJackson2MessageConverter {
return MappingJackson2MessageConverter()
}
}
然后我有一个侦听器(println
暂时供我检查),如:
@RabbitListener(queues = ["success.queue"])
fun receivedSuccessMessage(data: MyModel) {
println(data)
}
模型本身看起来像(再次简化只是为了测试):
@JsonIgnoreProperties(ignoreUnknown = true)
data class MyModel(
val input: Any,
val metadata: Any
)
现在,只要该队列收到消息,我得到的错误就是:
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [[B] to [com.models.MyModel] for GenericMessage [payload=byte[1429]
还要将我要接收的消息添加到该成功队列中,如下所示:
{"input":"somestuff", "metadata": "somestuff"}
我还刚刚注意到消息类型为content_type: application/octet-stream
。这是我无法控制的,因为那正是我从将消息放入其中的服务所收到的:
这是为什么的任何想法-我假设我执行的RabbitListenerConfigurer
会将所有消息从字节数组转换为我指定的任何模型。
任何帮助/想法都将不胜感激。
谢谢。
更新 好的,我已经开始工作了,但是我对某些事情感到困惑:
这是我添加的内容:
@Autowired
lateinit var connectionFactory : ConnectionFactory
@Bean
fun rabbitListenerContainerFactory(): SimpleRabbitListenerContainerFactory {
val factory = SimpleRabbitListenerContainerFactory()
factory.setConnectionFactory(connectionFactory)
factory.setAfterReceivePostProcessors(SomeBusiness())
return factory
}
然后是这样的实际转换:
class SomeBusiness : MessagePostProcessor {
@Throws(AmqpException::class)
override fun postProcessMessage(message: Message): Message {
println("WE WENT IN NOW")
println()
if (message.messageProperties.contentType == "application/octet-stream") {
message.messageProperties.contentType = "application/json"
}
return message
}
}
但是我不明白的是,我已经有了messageHandlerMethodFactory
函数,我假设它已经完成了监听消息的所有工作。现在,我有了rabbitListenerContainerFactory
,可以担心是否存在任何冲突。还是完全有效,也就是说,我需要rabbitListenerContainerFactory
来实现SimpleRabbitListenerContainerFactory
,这使我可以访问方法setAfterReceivePostProcessors
。
再次,任何解释都将不胜感激。
谢谢
答案 0 :(得分:0)
当您收到content_type: application/octet-stream
时,此设置无法更改。
您可以使用Spring Interceptor或Servlet Filter将内容类型application/octet-stream
转换为application/json
。
答案 1 :(得分:0)
请找到以下对我有用的资源
public void convertByteArrayToObject(Message<?> message) {
Object request = message.getPayload();
Object result = null;
try {
byte[] byteArray = (byte[]) request;
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
result = new ObjectInputStream(byteArrayInputStream).readObject();
} catch (ClassNotFoundException | IOException e) {
LOG.error(e.getMessage());
}
return result;
}