【问题标题】:Web app that delegates a task with a return value in jms使用 jms 中的返回值委派任务的 Web 应用程序
【发布时间】:2014-08-18 17:28:08
【问题描述】:

我被要求创建一个使用 JMS 的 2 个项目,即项目 A 和 B。 B 是一个 WEB 项目,有一个简单的页面,其中包含我输入两个日期(开始日期 - 结束日期)的表单。提交表单后,B 会要求 A 根据两个日期处理一个任务(查询一个文件)。然后 B 将在网页中显示结果。需要注意的是我需要在 jms 中执行此操作。

在我的 B 控制器中我正在考虑这个(简化。我正在使用弹簧)

@controller
Mycontroller{
   MyMessageProducer mp;

   @RequestMapping(....)
   public String(...){

     mp.sendMessage(...);

    //wait for the response here and render?

   }    
}

现在我不知道如何实现项目 A。如果 a 使用点对点消息传递(使用队列),那么这意味着 A 将必须显式地从队列中获取消息(我使用 activemq) .这很糟糕,因为 A 应该自动监听请求,不是吗?但是,如果我使用发布者-订阅者,在这种情况下发布者将是 B,客户端(因为 B 向 A 发送消息),我认为这是一个糟糕的解决方案。我应该使用哪种策略?

现在假设 A 成功接收到消息并查询文件,我将如何将结果发送回 B 以便 B 能够在网页中显示结果?有没有办法做到这一点?

(PS 我是 JMS 新手,虽然我已经根据教程实现了一个简单的生产者和接收者)

【问题讨论】:

    标签: spring web jms activemq


    【解决方案1】:

    IMO 最简单的方法是使用具有Gateways 概念的Spring Integration(另请参阅Enterprise Integration Patterns)。你可以只指定一个service-interface,它有一个带有返回值的方法。类似的东西

    public interface MessageProducer {
        @Gateway
        public String sendMessageAndGetReply(String name);
    }
    

    将创建接口的代理。当您从 <int:gateway> 元素引用它时。类似的东西

    <int:channel id="requestChannel"/>
    <int:channel id="replyChannel"/>
    
    <int:gateway id="messageProducerGateway" default-request-channel="requestChannel"
        default-reply-channel="replyChannel"
        service-interface="demo.MessageProducer">
    </int:gateway>
    
    <int-jms:outbound-gateway id="outboundJmsGateway"
        connection-factory="connectionFactory" reply-channel="replyChannel"
        request-channel="requestChannel" reply-destination-name="reply.queue"
        request-destination-name="request.queue">
    </int-jms:outbound-gateway>
    

    &lt;int-jms:outbound-gateway&gt; 会将消息发送到 jms 队列并接收回复。 connectionFactory 只是你常用的ConnectionFactory 实例(即ActiveMQConnectionFactoryCachingConnectionFactory

    在 jms 交互的“服务器”端,您将使用 &lt;int-jms:inbound-gateway&gt;,类似

    <int-jms:inbound-gateway id="inboundJmsGateway"
        request-channel="requestChannel" acknowledge="client"
        connection-factory="connectionFactory" request-destination-name="request.queue" />
    
    <int:service-activator id="messageHandler" ref="serverMessageHandler"
        input-channel="requestChannel">
    </int:service-activator>
    

    serverMessageHandler 只是一个简单的组件,它有一个方法来处理并向网关返回回复。

    @Component
    public class ServerMessageHandler {
    
        @ServiceActivator
        public String handleMessage(String message) {
            return "Hello, " + message;
        }
    }
    

    运行一个简单的演示

    AbstractApplicationContext client = new ClassPathXmlApplicationContext("demo-gateway.xml");
    AbstractApplicationContext server = new ClassPathXmlApplicationContext("demo-gateway-server.xml");
    MessageProducer producer = client.getBean(MessageProducer.class);
    String returnedMessage = producer.sendMessageAndGetReply("StackOverflow");
    System.out.println(returnedMessage);
    

    你会得到"Hello, StackOverflow"。一旦您对框架有了基本的了解,就没有太多的东西了。这个例子我给出了一个同步的例子。您可以在 github 的 spring-integration-samples 上查看完整示例(以及其他示例)。我会花一些时间阅读参考指南以熟悉基础知识。

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 2013-01-08
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多