简体   繁体   中英

Spring AMQP: error with annotation-driven listener endpoints

I'm trying to set up a simple Spring AMQP scenario, but am getting the following error:

Could not resolve method parameter at index 0 in method:
    public void handleMessage(HelloMessage),
    with 1 error(s): [Error in object 'msg': codes []; arguments [];
    default message [@Payload param is required]]

I don't understand the error message, I was under the impression I can use any POJO to send and receive a message, as per the documentation here .

It's a very simple setup:

main

public class Program {
private static ConfigurableApplicationContext applicationContext;

public static void main(String[] args) {
    try {
        startApp();
        System.out.println("Running...");
        System.in.read();
        applicationContext.close();
        System.out.println("Shutting down...");
    }
    catch (Throwable e) {
        e.printStackTrace();
    }
}

private static void startApp() {
    applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
    applicationContext.refresh();

    MessageSender messageSender = applicationContext.getBean(MessageSender.class);
    messageSender.sendMessage("hello", 1);
}

application-context.xml

    <context:component-scan base-package="org.abiri.amqpTest" />


    <rabbit:connection-factory id="connectionFactory"
                               host="localhost" port="5672"
                               username="guest" password="guest"/>

    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>

    <rabbit:admin connection-factory="connectionFactory"/>

    <rabbit:queue name="hello"/>

    <bean id="rabbitListenerContainerFactory"
          class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="concurrentConsumers" value="3"/>
        <property name="maxConcurrentConsumers" value="10"/>
    </bean>

    <rabbit:annotation-driven container-factory="rabbitListenerContainerFactory"/>

    <rabbit:listener-container connection-factory="connectionFactory" />

MessageSender

@Service
public class MessageSender {

    @Autowired
    private AmqpTemplate amqpTemplate;

    // Accessors...

    public void sendMessage(String message, Integer sillyNumber) {
        amqpTemplate.convertAndSend("hello",
            new HelloMessage(message, sillyNumber));
    }
}

MessageListener

@Component
public class MessageListener {

    @RabbitListener(queues = "hello")
    public void handleMessage(HelloMessage msg) {
        out.println(format("Received message: %s with silly number: %d",
                msg.getMessage(), msg.getSillyNumber()));
    }
}

HelloMessage

public class HelloMessage {
    private String  message;
    private Integer sillyNumber;

    // Empty constructor, full constructor and accessors
}

I am able to verify that the message was indeed sent and is in the queue:

在此输入图像描述

RabbitMQ default installation via homebrew.

Your issue is very simple!

To send any Java object over RabbitMQ with default SimpleMessageConverter you have to to mark your class as Serializable :

public class HelloMessage implements Serializable {
   ....
}

Of course, a listener application should have the same class in its CLASSPATH to have an ability to deserialize byte[] from payload (AMQP Message body) to the appropriate HelloMessage object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM