我有一个 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 请求(数据:abc
和 xyz
)。我如何才能确保响应正确答案而不仅仅是我从 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/