基于Spring与ActiveMQ实现HTTP请求响应的REST API问题求助
解决REST请求与JMS响应的关联问题
你的核心问题是同步HTTP请求与异步JMS消息的响应关联,这需要用到JMS标准的JMSCorrelationID属性来标记请求和对应的响应。下面是具体的修改方案,一步步帮你解决问题:
1. 修正RESTController的基础问题
首先你的RESTController继承Exception是完全没必要的,先把这个错误改掉,然后添加请求响应关联的核心逻辑:
@RestController public class RESTController { // 移除extends Exception @Autowired CamelContext camelContext; @Autowired JmsTemplate jmsTemplate; @GetMapping("/{id}") public ResponseEntity<CheckMessage> testCamel(@PathVariable String id) { // 生成唯一的关联ID,用来匹配后续的响应消息 String correlationId = UUID.randomUUID().toString(); // 创建请求消息,并通过后置处理器设置JMS关联ID CheckMessage outMsg = new CheckMessage(id); jmsTemplate.convertAndSend("ws-out", outMsg, message -> { message.setJMSCorrelationID(correlationId); return message; }); // 根据关联ID筛选接收对应的响应,设置超时时间避免无限等待 CheckMessage inMsg = (CheckMessage) jmsTemplate.receiveSelectedAndConvert( "ws-in", "JMSCorrelationID = '" + correlationId + "'", 5000 // 5秒超时,可根据业务调整 ); if (inMsg == null) { return ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body(null); } return ResponseEntity.ok(inMsg); } }
2. 确保校验服务回传关联ID
你提到校验服务代码正常,但需要确保它在发送响应时,把收到的请求的关联ID回传过来。校验服务的JMS监听器应该修改成这样:
@Service public class CheckService { @Autowired JmsTemplate jmsTemplate; @JmsListener(destination = "cs-in") public void processCheckMessage(CheckMessage request, @Header(JmsHeaders.CORRELATION_ID) String correlationId) { // 执行你的校验逻辑,修改CheckMessage的属性为true request.setChecked(true); // 发送响应到ws-in队列,同时设置关联ID为收到的请求的ID jmsTemplate.convertAndSend("ws-in", request, message -> { message.setJMSCorrelationID(correlationId); return message; }); } }
3. 配置Camel路由(如果还未配置)
因为你用了Camel和ActiveMQ,需要确保ws-out队列的消息能路由到cs-in队列,添加一个Camel路由组件:
@Component public class JmsRoute extends RouteBuilder { @Override public void configure() throws Exception { // 从ws-out队列接收消息,转发到cs-in队列 from("activemq:ws-out") .to("activemq:cs-in"); } }
4. 移除冗余的WSListener
你当前的WSListener是空实现,而且我们已经在RESTController中直接接收响应了,这个监听器会导致消息被重复消费,建议直接删除。
关键注意点
- JMSCorrelationID的作用:这是JMS规范中用于关联请求和响应的标准属性,通过它可以精准匹配当前HTTP请求对应的JMS响应,不会拿到其他请求的消息。
- 超时时间设置:必须给
receiveSelectedAndConvert设置超时,否则HTTP请求会无限阻塞,导致客户端超时或服务器资源浪费。 - 消息序列化:确保
CheckMessage类实现了Serializable接口,否则JMS无法完成对象的序列化和反序列化。
内容的提问来源于stack exchange,提问作者Kaigo
相关产品推荐
相关产品推荐

