1

我正在寻找可以帮助我将 spring REST Web 服务与消息总线(RabbitMQ)集成的 spring 模块。REST Web 服务充当来自客户端的 AMQP 消息的消费者。每当通过总线发送消息时,它就是一条 AMQP 消息,并且要使其与 REST 一起使用,必须将其转换为 REST 调用。有谁知道使其工作的现有解决方案?

4

1 回答 1

3

我个人没有看到其中的价值,即使用同步 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) REST Endpoint 添加消息

显示消息到达的 RabbitMQ Admin Client 的屏幕截图 RabbitMQ 显示排队消息

实际消息截图 RabbitMQ 消息详细信息

注意:这是一个非常基本的示例,只有一个 RabbitMQ 交换/队列,不包含安全性或您可能想要的任何其他基本内容!

于 2015-05-02T16:03:15.290 回答