我正在尝试使用 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.TransportFactory
的 org.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/