如何在 Spring Boot 中使用 JMS 和 ActiveMQ“经典”发送自定义对象?

问题描述 投票:0回答:1

我正在尝试使用 ActiveMQ“Classic”发送

ObjectMessage
。为此,我创建了两个 Spring Boot 项目 - 客户和生产者。我使用下面的代码从生产者发送。

@GetMapping("/send-letter")
public String sendLetter() {
    var letter = new Letter("Hello " + UUID.randomUUID(), "Jack", "Jill");

    template.convertAndSend("test_letter", letter);
    return "Letter sent!";
}

然后,我使用下面的代码来捕获客户中的该对象。

@JmsListener(destination = "test_letter")
public void getTest(Letter letter) {
    System.out.printf("From %s to %s with content %s", letter.getSender(), letter.getReceiver(), letter.getContent());
}

此外,这是我在

application.yaml
文件上的配置。我也尝试使用
trust-all: true
参数但没有任何效果。

spring:
  activemq:
    broker-url: tcp://localhost:61616
    user: admin
    password: admin
    packages:
      trusted: com.example.demo.Entities.Letter

完全相同的结构适用于字符串。

我能够将

ObjectMessage
发送到 ActiveMQ,正如我从管理面板中看到的那样,但是当我运行侦听器时,它会抛出一堆错误,我将“主要”错误放在下面:

org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.example.demo.controller.MessageConsumer.getTest(com.example.demo.Entities.Letter)' threw exception
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118) 
Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not convert JMS message
    at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:255) 
Caused by: jakarta.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class com.example.demo.Entities.Letter! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to configure trusted classes.
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:49) ~[activemq-client-jakarta-5.18.2.jar:5.18.2]
Caused by: java.lang.ClassNotFoundException: Forbidden class com.example.demo.Entities.Letter! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to 

我通过阅读本教程编写了代码。我阅读并尝试了我能找到的关于此问题的所有答案(包括将对象转换为字节),但我无法使它们工作。

我期待在客户控制台中看到该对象。

spring-boot jms activemq
1个回答
0
投票

看起来您将受信任的包配置为使用 class 名称(即

com.example.demo.Entities.Letter
)而不是 package 名称(即
com.example.demo.Entities
)。尝试用这个代替:

spring:
  activemq:
    broker-url: tcp://localhost:61616
    user: admin
    password: admin
    packages:
      trusted: com.example.demo.Entities

也就是说,您应该尽可能避免使用 JMS

ObjectMessage
。它们依靠 Java 序列化来编组和解组其对象负载。这不仅速度慢,而且通常被认为是不安全的,因为恶意负载可以利用主机系统。为此创建了许多 CVE,这也是您必须首先显式配置哪些包受信任的原因。使用
ObjectMessage
还会限制架构的灵活性,因为非 JMS 客户端无法使用它们。

我强烈建议您使用其他格式的消息,例如JSON、XML、Protobuf 等。这将更快、更安全,并且与其他语言和协议广泛兼容,使您的架构更加健壮。

© www.soinside.com 2019 - 2024. All rights reserved.