You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:51:07