我正在寻找可以帮助我将 spring REST Web 服务与消息总线(RabbitMQ)集成的 spring 模块。REST Web 服务充当来自客户端的 AMQP 消息的消费者。每当通过总线发送消息时,它就是一条 AMQP 消息,并且要使其与 REST 一起使用,必须将其转换为 REST 调用。有谁知道使其工作的现有解决方案?
1 回答
我个人没有看到其中的价值,即使用同步 REST 接口来使用一些异步 AMQP 消息,因为您有点失去了像 RabbitMQ 这样的异步消息系统的目的/优势。
AMQP 的伟大之处在于它是一种有线协议并且不依赖于一种语言(例如,JMS 与 Java 非常相关)。这意味着您可以使用 Java / Spring / AMQP 库、Node.JS / AMQP 库、C# / AMQP 库等。这篇文章比我更好地解释了这些优势http://www.wmrichards.com/amqp.pdf 我的意思是,如果您正在寻找 REST 在另一种语言/系统等与 RabbitMQ 之间建立桥梁,那么我首先会调查其他语言/系统是否支持 AMQP 库。
但是,如果你必须有一个 REST'ful 接口,你可以使用 SpringMVC 创建一个简单的控制器并注入private AmqpTemplate amqpTemplate;
一些方法。这有效地创建了您的 REST-to-AMQP 桥/代理。spring 配置/Java Controller 如下(注意这已经过测试并且有效): -
/spring/restAmqpContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
<!-- Location of "config.properties" to override RabbitMQ connection details if required. -->
<context:property-placeholder ignore-resource-not-found="true"
location="classpath:/config.properties,
${DATA_HOME:}/config.properties" />
<bean class="com.bobmarks.controller.RestAmqpController">
<property name="amqpTemplate" ref="amqpTemplate"/>
</bean>
<mvc:default-servlet-handler />
<mvc:annotation-driven/>
<rabbit:connection-factory id="amqpConnectionFactory"
host="${rabbitmq.host:localhost}"
port="${rabbitmq.port:5672}"
username="${rabbitmq.username:guest}"
password="${rabbitmq.password:guest}"
publisher-confirms="${rabbitmq.publisher.confirms:true}"
publisher-returns="${rabbitmq.publisher.returns:true}" />
<rabbit:template id="amqpTemplate" connection-factory="amqpConnectionFactory" mandatory="true" />
<rabbit:admin id="rabbitAdmin" connection-factory="amqpConnectionFactory" />
<rabbit:queue name="my_queue" />
<rabbit:direct-exchange name="my_exchange">
<rabbit:bindings><rabbit:binding queue="my_queue" key="my_binding" /></rabbit:bindings>
</rabbit:direct-exchange>
RestAmqpController.java
package com.bobmarks.controller;
import java.util.Date;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Simple Rest To AMQP Controller.
*/
@Controller
@RequestMapping(value = "/rest2amqp")
public class RestAmqpController {
private AmqpTemplate amqpTemplate;
public RestAmqpController() {}
public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
this.amqpTemplate = amqpTemplate;
}
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<String> message(@RequestParam(value = "message") String message) {
try {
amqpTemplate.convertAndSend("my_exchange", "my_binding", message);
return new ResponseEntity<String>("Message sent to AMQP queue at: " + new Date(), HttpStatus.OK);
}
catch (AmqpException amqpEx) {
return new ResponseEntity<String>(amqpEx.getMessage(), HttpStatus.BAD_REQUEST);
}
}
}
这些以通常的方式(Tomcat / Spring Boot / 等)打包,例如,如果项目被称为数据,则发送消息的 REST 端点将如下所示:-
http://localhost/data/rest2amqp?message=Hello_World
这可能通过屏幕截图更好地显示。
提交消息截图(仅使用FireFox)
显示消息到达的 RabbitMQ Admin Client 的屏幕截图
实际消息截图
注意:这是一个非常基本的示例,只有一个 RabbitMQ 交换/队列,不包含安全性或您可能想要的任何其他基本内容!