java - 同步异步通信

标签 java rest spring-boot ibm-mq

我有一个 REST 服务,它接收一些数据并通过异步 IBM MQ 请求检查数据。

REST Controller :

@RestController
@RequestMapping("/request")
public class RequestController {

    @RequestMapping(method = RequestMethod.POST)
    public Response postRequest(@RequestBody Request request) {

        String data = request.getData();

        jmsSender.send(data);

        // Now I need the response from MQ
        // String mqResponse = ...
        if (mqIsValid(mqResponse)) {
            return createValidResponse();
        }
        return createNotValidResponse();
    }
}

MQ 发送方:

@Service
public class JmsSender {

    public void send(String data) {
        jmsTemplate.convertAndSend("QUEUE.TO.MQ", data);
    }

}

MQ 接收器:

@Component
public class JmsReceiver {

    @JmsListener(destination = "QUEUE.FROM.MQ, containerFactory = "DefaultJmsListenerContainerFactory")
    public void receiveMessage(String message) {
        // How to pass the message to the controller?
    }

}

如何等待来自 MQ 的正确数据在 Controller 中创建正确的响应?

是否可以像描述的那样使用BlockingQueue here ?就我而言,我必须区分数据。我不能只从阻塞队列中取出第一个数据。

如果同时有两个 REST 请求(数据:abcxyz)。我如何才能确保响应正确答案而不仅仅是我从 MQ 获得的第一个答案?

我也无法更改 MQ 接口(interface)。

最佳答案

尝试使用如下所示的 CountDownLatch。

@RestController
@RequestMapping("/request")
public class RequestController {

    @RequestMapping(method = RequestMethod.POST)
    public Response postRequest(@RequestBody Request request) {
        final CountDownLatch jmsLatch = new CountDownLatch (1);

        String data = request.getData();

        jmsSender.send(data, jmsLatch);

        try {
            latch.await();  // wait untill latch counted down to 0
        } catch (InterruptedException e) {
            return createNotValidResponse();
        }

        return createValidResponse();
    }
}

修改发送方法以从 Controller 获取CountDownLatch。

@Service
public class JmsSender {

    public void send(String data, final CountDownLatch jmsLatch) {
        jmsLatch.await();
        jmsTemplate.convertAndSend("QUEUE.TO.MQ", data);
    }

}

修改接收方法以从 Controller 获取相同的 CountDownLatch。

@Component
public class JmsReceiver {

    @JmsListener(destination = "QUEUE.FROM.MQ", containerFactory = "DefaultJmsListenerContainerFactory")
    public void receiveMessage(String message, final CountDownLatch jmsLatch) {
        // Pass the message to the controller
        jmsLatch.countDown();
    }

}

这里的技巧是您必须将相同的 CountDownLatch 实例从 Controller 传播到发送方和接收方类,并在收到消息后调用 countDown 方法。

关于java - 同步异步通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41507982/

相关文章:

java - 横向模式: why do I get different result on my computer screen and different on my phone?

java - Spring Boot Rest MVC。 Mockito 和放心。无法模拟实例

spring-boot - spring boot 微服务 docker 实现中 google oauth2 的无效重定向 uri 参数

java - 在 Spring Boot 2.4 中用我的配置文件 dev 覆盖属性

java - 发生字符串标记化错误

java.lang.NullPointerException 查询错误

java - Spring 启动休息 api : how to respond gracefully if Request Body is sent in incorrect format?

rest - 为我们在 Apiary.io 中的每个响应指定描述

rest - React 组件和服务之间通信的最佳实践是什么?

java - 单元测试需要很多接口(interface)?