Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring引导RabbitMQ接收器Jackson反序列化到POJO_Java_Json_Spring_Jackson_Rabbitmq - Fatal编程技术网

Java Spring引导RabbitMQ接收器Jackson反序列化到POJO

Java Spring引导RabbitMQ接收器Jackson反序列化到POJO,java,json,spring,jackson,rabbitmq,Java,Json,Spring,Jackson,Rabbitmq,我有一个SpringBoot项目,我正在尝试与rabbitmq服务器集成,这样我就可以在队列中发布和读取消息 以下是我的rabbitmq配置(编辑为仅显示相关详细信息): 以下是我的接收器类别: public interface Receiver { void handleMessage(FooA message); } @Component public class RabbitReceiver implements Receiver { @Override publ

我有一个SpringBoot项目,我正在尝试与rabbitmq服务器集成,这样我就可以在队列中发布和读取消息

以下是我的rabbitmq配置(编辑为仅显示相关详细信息):

以下是我的接收器类别:

public interface Receiver {
    void handleMessage(FooA message);
}

@Component
public class RabbitReceiver implements Receiver {
    @Override
    public void handleMessage(FooA message) {
        System.out.println(message);
    }
}
还有我的pojo:

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;
    }
}
但当我尝试从队列中读取时,会出现以下错误:

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:我将方法更改为:

@Override
public void handleMessage(byte[] message) {
    System.out.println(message);
}
虽然有效,但完全无法使用。它就是这样显示的:


如何将其映射到我的pojo
FooA

看起来消息是作为字符串而不是JSON发布的。 你就是这么看的

"payload_encoding": "string"
Spring可以自动将该字符串转换为字节[],如屏幕截图所示

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

@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory,MessageConverter rabbitJsonMessageConverter) {
    RabbitTemplate template = new RabbitTemplate(connectionFactory);
    template.setMessageConverter(rabbitJsonMessageConverter);
    return template;
}

这应该可以正确地将消息发布为JSON。

我刚刚让类实现了可序列化的接口,删除了JsonMessageConverter。Json和Serializable相互冲突,因此无法工作

将bytearray转换为字符串,并使用jackson映射器(ObjectMapper)映射到pojo。您的映射器上有配置:例如

 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())

你做的每件事都是正确的。但是您没有提供任何方法来接收和处理您的消息。这就是为什么您得到了ListenerExecutionFailedException:Failed调用目标方法“handleMessage”

要修复此更改,请输入以下代码:

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


本文介绍了如何以更简单的方式解决此问题:

配置:

@Bean
public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) {
    final var rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setMessageConverter(producerJackson2MessageConverter());
    return rabbitTemplate;
}

@Bean
public Jackson2JsonMessageConverter producerJackson2MessageConverter() {
    return new Jackson2JsonMessageConverter();
}
听众:

@RabbitListener(queues = MessagingApplication.QUEUE_SPECIFIC_NAME)
public void receiveMessage(final CustomMessage customMessage) {
    log.info("Received message and deserialized to 'CustomMessage': {}", customMessage.toString());
}
POJO:


我猜正在使用某个数组调用
handleMessage
,并且没有定义这样的方法。@redflar3是的!在上面进行了编辑不幸的是,我的配置在将消息放入队列时已经有了模板的这段代码,但它仍然是字符串编码的。您序列化了哪个类
@Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
        return new MessageListenerAdapter(receiver, "handleMessage");
    }
@Bean
public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) {
    final var rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setMessageConverter(producerJackson2MessageConverter());
    return rabbitTemplate;
}

@Bean
public Jackson2JsonMessageConverter producerJackson2MessageConverter() {
    return new Jackson2JsonMessageConverter();
}
@RabbitListener(queues = MessagingApplication.QUEUE_SPECIFIC_NAME)
public void receiveMessage(final CustomMessage customMessage) {
    log.info("Received message and deserialized to 'CustomMessage': {}", customMessage.toString());
}
public record CustomMessage(@JsonProperty("text") String text,
                            @JsonProperty("priority") int priority,
                            @JsonProperty("secret") boolean secret)
        implements Serializable {
}