首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring Boot RabbitMQ接收机Jackson反序列化为POJO

Spring Boot RabbitMQ接收机Jackson反序列化为POJO
EN

Stack Overflow用户
提问于 2017-08-22 21:25:18
回答 5查看 7.5K关注 0票数 3

我有一个spring引导项目,在这个项目中,我试图与一个rabbitmq服务器集成,这样我就可以将消息发布到/从队列中读取。

以下是我的rabbitmq配置(编辑后只显示相关细节):

代码语言:javascript
运行
复制
@Configuration
@ConfigurationProperties(prefix="rabbit")
public class RabbitConfig {
    private String queue;

    @Bean
    Queue queue() {
        return new Queue(queue, durable);
    }

    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, Queue queue,
                                             MessageListenerAdapter listenerAdapter, MessageConverter messageConverter) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueues(queue);
        container.setMessageListener(listenerAdapter);
        container.setMessageConverter(messageConverter);
        return container;
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver);
    }

    public void setQueue(String queue) {
        this.queue = queue;
    }
}

这是我的接受者课程:

代码语言:javascript
运行
复制
public interface Receiver {
    void handleMessage(FooA message);
}

@Component
public class RabbitReceiver implements Receiver {
    @Override
    public void handleMessage(FooA message) {
        System.out.println(message);
    }
}

我的波乔:

代码语言:javascript
运行
复制
public class FooA {}
    private double num;
    private Map<String, String> map = new HashMap();

    public FooA() {
    }

    public FooA(double num, Map<String, String> map) {
        this.num = num;
        this.map = map;
    }

    public int getnum() {
        return num;
    }

    public Map<String, String> getMap() {
        return map;
    }
}

我能够成功地将FooA消息对象发布到队列中。下面是队列中的样子:

代码语言:javascript
运行
复制
[
    {
        "payload_bytes": 41,
        "redelivered": false,
        "exchange": "amq.fanout",
        "routing_key": "",
        "message_count": 0,
        "properties": {
            "priority": 0,
            "delivery_mode": 2,
            "headers": {
                "__TypeId__": "com.test.FooA"
            },
            "content_encoding": "UTF-8",
            "content_type": "application/json"
        },
        "payload": "{\"num\":1.2,\"map\":{}}",
        "payload_encoding": "string"
    }
]

但是,当我试图从队列中读取时,我会得到以下错误:

代码语言:javascript
运行
复制
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Failed to invoke target method 'handleMessage' with argument type = [class [B], value = [{[B@75a7bfc9}]
    at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:408) ~[spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:298) ~[spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:822) ~[spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:745) ~[spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:97) [spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:189) ~[spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1276) [spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:726) ~[spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1219) [spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1189) [spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1500(SimpleMessageListenerContainer.java:97) [spring-rabbit-1.7.3.RELEASE.jar:na]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1421) [spring-rabbit-1.7.3.RELEASE.jar:na]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
Caused by: java.lang.NoSuchMethodException: com.test.RabbitReceiver.handleMessage([B)
    at java.lang.Class.getMethod(Class.java:1786) ~[na:1.8.0_121]
    at org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:174) ~[spring-core-4.3.9.RELEASE.jar:4.3.9.RELEASE]
    at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:386) ~[spring-rabbit-1.7.3.RELEASE.jar:na]
    ... 12 common frames omitted

我做错了什么?

编辑1:我将方法更改为:

代码语言:javascript
运行
复制
@Override
public void handleMessage(byte[] message) {
    System.out.println(message);
}

效果很好,但完全不能用。它就是这样出现的:

如何将它映射到我的pojo FooA

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-08-24 23:29:48

我刚刚让实现Serializable接口的类删除了JsonMessageConverter。Json和Serializable是相互冲突的,所以它不起作用。

票数 2
EN

Stack Overflow用户

发布于 2017-11-22 21:11:25

将字节数组转换为字符串,并使用jackson (ObjectMapper)映射到pojo。你的地图上有配置。

代码语言:javascript
运行
复制
 this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    this.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
    this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
    this.registerModule(new JavaTimeModule())
票数 1
EN

Stack Overflow用户

发布于 2017-08-22 21:47:24

看起来,消息是以字符串形式发布的,而不是JSON。这就是你所看到的

代码语言:javascript
运行
复制
"payload_encoding": "string"

Spring可以自动将此字符串转换为byte[],如屏幕截图所示。

还需要在RabbitTemplate上设置消息转换器,如下所示:

代码语言:javascript
运行
复制
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory,MessageConverter rabbitJsonMessageConverter) {
    RabbitTemplate template = new RabbitTemplate(connectionFactory);
    template.setMessageConverter(rabbitJsonMessageConverter);
    return template;
}

这将正确地将消息发布为JSON。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45827213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档