【问题标题】:How to Send message via apacheMQ in between two servlets?如何在两个 servlet 之间通过 apacheMQ 发送消息?
【发布时间】:2015-07-12 01:29:36
【问题描述】:

我正在尝试将 apacheMQ 集成到我在 Tomcat 上运行的 Web 应用程序中。我找到了一些关于本地集成的教程(我不打算进行全局集成),但我不确定如何进行。对于初学者来说,所有的教程似乎都很混乱。

能否请您看一下我的代码并建议我是否在正确的道路上实现它?我的意图是从一个 servlet 发送一些消息(将其添加到队列中),然后从具有不同 servlet 的队列中读取这些消息。

此代码基于THIS TUTORIAL

消息处理类:

public class Messenger {

    public static void sendMessage(String msg) {
        // configure the broker
        try {
            // Create a ConnectionFactory
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                    "vm://localhost");

            // Create a Connection
            Connection connection = connectionFactory.createConnection();
            connection.start();

            // Create a Session
            Session session = connection.createSession(false,
                    Session.AUTO_ACKNOWLEDGE);

            // Create the destination (Topic or Queue)
            Destination destination = session.createQueue("TEST.FOO");

            // Create a MessageProducer from the Session to the Topic or Queue
            MessageProducer producer = session.createProducer(destination);
            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

            // Create a messages
            TextMessage message = session.createTextMessage(msg);

            // Tell the producer to send the message
            System.out.println("Sent message: " + message.getText());
            producer.send(message);

            // Clean up
            session.close();
            connection.close();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void readQueue() {
        try {

            // Create a ConnectionFactory
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                    "vm://localhost");

            // Create a Connection
            Connection connection = connectionFactory.createConnection();
            connection.start();

            // Create a Session
            Session session = connection.createSession(false,
                    Session.AUTO_ACKNOWLEDGE);

            // Create the destination (Topic or Queue)
            Destination destination = session.createQueue("TEST.FOO");

            // Create a MessageConsumer from the Session to the Topic or Queue
            MessageConsumer consumer = session.createConsumer(destination);

            // Wait for a message
            Message message = consumer.receive(1000);

            if (message instanceof TextMessage) {
                TextMessage textMessage = (TextMessage) message;
                String text = textMessage.getText();
                System.out.println("Received: " + text);
            } else {
                System.out.println("Received: " + message);
            }

            consumer.close();
            session.close();
            connection.close();
        } catch (Exception e) {
            System.out.println("Caught: " + e);
            e.printStackTrace();
        }
    }

}

目前,我在控制台中打印所有内容就足够了,因为此示例仅用于测试和调试目的。

发送和接收 servlet:

public class SendMessageServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");

        Messenger.sendMessage("Test message");


    }

}

public class ReadQueueServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");

        Messenger.readQueue();

    }

}

访问ReadQueueServlet的结果只是“Received: null”。

我不确定在这种情况下是否应该为我的 Web 应用程序创建 context.xml,但我也尝试过。我将以下内容放在WEB-INF/META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Resource auth="Container"
          name="jms/ConnectionFactory"
          type="org.apache.activemq.ActiveMQConnectionFactory"
          description="JMS Connection Factory"
          factory="org.apache.activemq.jndi.JNDIReferenceFactory"
          brokerURL="vm://localhost?brokerConfig=xbean:activemq.xml"
          brokerName="MyActiveMQBroker"/>

<Resource auth="Container"
          name="jms/FooQueue"
          type="org.apache.activemq.command.ActiveMQQueue"
          description="JMS queue"
          factory="org.apache.activemq.jndi.JNDIReferenceFactory"
          physicalName="FOO.QUEUE"/>
</Context>

感谢任何帮助。

【问题讨论】:

  • 不要使用vm://localhost,请使用“failover://tcp://localhost:61616”,我想你没有提到端口号,连接不成功跨度>
  • 我应该只在代码中还是在 context.xml 中更改它?我什至应该使用上下文吗?
  • 无论您在哪里使用 vm://localhost,请使用“failover://tcp://localhost:61616”,因为端口是必须的
  • 我改变了它,但现在 servlet 永远停留在“等待本地主机”中
  • 你的 MQ 服务器启动了,你可以尝试从浏览器访问 localhost:61616

标签: java tomcat servlets web-applications activemq


【解决方案1】:

访问ReadQueueServlet的结果只是“Received: null”。

这是因为队列中没有消息。

        // Wait for a message
        Message message = consumer.receive(1000);

        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            String text = textMessage.getText();
            System.out.println("Received: " + text);
        } else {
            System.out.println("Received: " + message);
        }

如果看到documentation的接收方法

返回: 为该消息消费者生成的下一条消息,如果超时或该消息消费者同时关闭,则返回 null

因此,在时间到期后,您将获得 null。您的代码进入 else 块并打印为 null 的消息。

【讨论】:

  • 这就是我意识到的......我的问题是为什么没有发送消息以及如何正确实现它。
  • 代码乍一看对我来说是正确的。 Active MQ 提供了一个 Web 门户来查看队列及其内容。停止你的消费者。只需运行生产者并查看队列内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2013-07-26
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多