java - 无法通过 Spring Boot 通过 STOMP 连接到 ActiveMQ 代理

标签 java spring-boot jms activemq stomp

我正在尝试使用 Spring Boot 连接到在本地计算机上运行的 ActiveMQ 代理,如下所示 link

在链接中,使用了内存代理,但我更热衷于使用代理服务器,在我的例子中我使用的是 ActiveMQ

我通过类路径中存在的文件 application.properties 中的以下配置为 Spring 指定 activemq 代理

spring.activemq.broker-url=stomp://localhost:61611
spring.activemq.password=password
spring.activemq.user=admin

下面是我的 pom.xml 的依赖项

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.2.RELEASE</version>
</parent>

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-broker</artifactId>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-stomp -->
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-stomp</artifactId>
    </dependency>

</dependencies>

下面是我在本地计算机上启动服务器后 ActiveMQ 的日志

INFO | Refreshing org.apache.activemq.xbean.XBeanBrokerFactory$1@5419f379: startup date [Sun May 07 07:17:36 IST 2017]; root of context hierarchy
INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[F:\Softwares\Browser\apache-activemq-5.14.5-bin\apache-activemq-5.14.5\bin\..\data\kahadb]
INFO | KahaDB is version 6
INFO | Recovering from the journal @1:2260893
INFO | Recovery replayed 3154 operations from the journal in 0.309 seconds.
INFO | PListStore:[F:\Softwares\Browser\apache-activemq-5.14.5-bin\apache-activemq-5.14.5\bin\..\data\localhost\tmp_storage] started
INFO | Apache ActiveMQ 5.14.5 (localhost, ID:FOOTBALL_FIELD-63581-1494121658754-0:1) is starting
INFO | Listening for connections at: tcp://0.0.0.0:61610?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector openwire started
INFO | Listening for connections at: amqp://0.0.0.0:5670?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector amqp started
INFO | Listening for connections at: stomp://0.0.0.0:61611?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector stomp started
INFO | Listening for connections at: mqtt://0.0.0.0:1880?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector mqtt started
WARN | ServletContext@o.e.j.s.ServletContextHandler@338c99c8{/,null,STARTING} has uncovered http methods for path: /
INFO | Listening for connections at ws://127.0.0.1:61612?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector ws started
INFO | Apache ActiveMQ 5.14.5 (localhost, ID:FOOTBALL_FIELD-63581-1494121658754-0:1) started

Application.java

@SpringBootApplication
@EnableJms
public class Application {

@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    // This provides all boot's default to this factory, including the message converter
    configurer.configure(factory, connectionFactory);
    // You could still override some of Boot's default if necessary.
    return factory;
}

@Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
}

public static void main(String[] args) {
    // Launch the application
    ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

    JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);

    // Send a message with a POJO - the template reuse the message converter
    System.out.println("Sending an email message.");
    jmsTemplate.convertAndSend("mailbox", new Email("info@example.com", "Hello"));
}

}

请求 DTO 类电子邮件

public class Email {

private String to;
private String body;

//getter setters for fields
//constructors 

@Override
public String toString() {
    return String.format("Email{to=%s, body=%s}", getTo(), getBody());
}

}

响应 DTO 类 ** **

@Component
public class Receiver {

@JmsListener(destination = "mailbox", containerFactory = "myFactory")
public void receiveMessage(Email email) {
    System.out.println("Received <" + email + ">");
}

}

现在,当我执行 Spring Boot 应用程序时,出现错误,其堆栈跟踪如下

    Exception in thread "main" org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not create Transport. Reason: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=localhost}
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
    at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:570)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:658)
    at hello.Application.main(Application.java:49)
Caused by: javax.jms.JMSException: Could not create Transport. Reason: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=localhost}
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36)
    at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:333)
    at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:346)
    at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:304)
    at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:244)
    at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:180)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:474)
    ... 3 more
Caused by: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=localhost}
    at org.apache.activemq.transport.TransportFactory.doConnect(TransportFactory.java:126)
    at org.apache.activemq.transport.TransportFactory.connect(TransportFactory.java:65)
    at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:331)

因此,我无法通过 Spring Boot 连接到本地计算机上运行的 ActiveMQ 代理。

我的要求是仅在 Spring Boot 中通过 ActiveMQ 代理在 STOMP 上构建 JMS 发送器和接收器。但是我无法连接到在本地运行的 ActiveMQ 实例的 STOMP URL。

更新:2017 年 5 月 11 日:

经过大量调试,我设法发现在org.apache.activemq.transport.TransportFactory类的第120行有这样的代码Transport Transport = createTransport(location, wf) 正在调用 org.apache.activemq.transport.TransportFactoryorg.apache.activemq.transport.tcp.TcpTransportFactory 实现,而不是 org.apache.activemq.transport.stomp.StompTransportFactory 或者事实上,activemq-stomp.jar 中可用的任何 StompTransportFactory 实现都存在于类路径中。我想知道是否有人可以告诉我如何选择合适的 TransportFactory 实现。

我在这个问题上坚持了将近三天。任何类型的帮助或建议将不胜感激:)

干杯!

最佳答案

您是否有任何理由想要在 Java 中使用 STOMP 来代替使用普通的 ActiveMQ Java 客户端和 VM 或 TCP 等协议(protocol)? STOMP 是为纯文本设计的...您的异常(exception)是由于您正在使用 ActiveMQ 客户端来表达 STOMP,但它无法做到这一点,并且要做到这一点,您需要一些其他库来支持 spring stomp,但它并不完全是这样你尝试做什么http://docs.spring.io/spring-integration/reference/html/stomp.html

如果你需要STOMP,你可以使用这个lib并配置相应的bean https://github.com/fusesource/stompjms

更新

正如我在这次测试中看到的那样 https://github.com/fusesource/stompjms/blob/master/stompjms-activemq-test/src/test/java/org/fusesource/stomp/activemq/ActiveMQJmsStompTest.java 由于它实现了 JMS API,因此很容易将该库集成到任何 java 或 spring 客户端。 您必须为 ConnectionFactory 定义一个 bean:

添加到您的application.properties

jms.broker.url=tcp://localhost:61611

并更新您的配置:

@Value("${jms.broker.url}")
public String host;

@Bean
public ConnectionFactory connectionFactory() throws Exception {
   StompJmsConnectionFactory result = new StompJmsConnectionFactory();
   result.setBrokerURI(host);
   return result;
}

关于java - 无法通过 Spring Boot 通过 STOMP 连接到 ActiveMQ 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43831393/

相关文章:

java - Android @NonNull 的用处

java - 无法在浏览器上将 Spring Boot XSRF-TOKEN 标志设置为安全

java - 包含带有列表的查询的 jpa

java - 在进入页面时创建了许多 session ,而不是一个。为什么?

java - 如何在 JUnit 测试中使用 ObjectMapper - Spring Boot 应用

java - 如何在 JMS 中初始化初始上下文

java - 通过 JMS 使用 Oracle 高级队列 : NPE thrown at AQjmsProducer. jdbcEnqueue

java - 我正在使用 Camick 的 ListTableModel 和 RowTableModel,JTABLE 中没有数据

java - 重构 - 在 Netbeans 8.0.2 中提取方法对象

java - 使用 JMS,如何获取特定目标的最大消息大小?