Apache ActiveMQ Artemis将TextMessage转换为ObjectMessage



我有一个用例,需要将消息从一种类型转换为另一种类型(即TextMessage->ObjectMessage(。

我发现,当在队列之间转移时,可以选择转换消息。我已经按照文档中的说明实现了Transformer接口。

import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.core.server.transformer.Transformer;
import javax.jms.ObjectMessage;

public class TypeTransformer implements Transformer {

@Override
public Message transform(Message message) {
return message;
}
}

但我现在开始意识到,从org.apache.activemq.artemis.api.core.Message转换为javax.jms.ObjectMessage可能是不可能的?

这是对的吗?这是不能做到的,还是有其他办法?

从技术上讲,应该可以将javax.jms.TextMessage转换为javax.jms.ObjectMessage,但这可能很麻烦。以下是一些需要注意的重要事项:

  • javax.jms.TextMessagejavax.jms.ObjectMessageorg.apache.activemq.artemis.api.core.Message都只是接口javax版本是您在客户端上使用的,Message版本是在代理上使用的。每种类型的消息的数据都以不同的方式存储在底层消息实现中
  • 要放入ObjectMessage中的Java对象的需要位于broker的类路径上。这在正常情况下是不需要的,因为代理本身永远不会序列化或反序列化对象
  • 你真的应该尽可能避免ObjectMessageObjectMessage对象依赖Java序列化来封送和解组其对象负载。这个过程通常被认为是不安全的(而且很慢!(,因为恶意负载可能会利用主机系统。已经为此创建了许多CVE。出于这个原因,大多数JMS提供程序强制用户显式地将可以使用ObjectMessage消息交换的包列入白名单。例如,以下是ActiveMQ Artemis的相关文档。使用JMSObjectMessage还有许多与安全性无关的其他问题,您应该了解这些问题

假设您了解所有应该能够使用以下代码转换消息的信息:

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.apache.activemq.artemis.api.core.ICoreMessage;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.server.transformer.Transformer;
public class TypeTransformer implements Transformer {
@Override
public Message transform(Message message) {
ICoreMessage coreMessage = message.toCore();
try {
// get the data from the TextMessage
SimpleString mySimpleString = coreMessage.getBodyBuffer().readNullableSimpleString();
if (mySimpleString == null) {
// no text in the message so no transformation can be done
return message;
}
String myString = mySimpleString.toString();
// parse the data from the TextMessage and set it on the serializable object
Serializable object = new MySerializable();         
// turn serializable object into byte array and write it to the message
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
byte[] data = baos.toByteArray();
coreMessage.getBodyBuffer().clear();
coreMessage.getBodyBuffer().writeInt(data.length);
coreMessage.getBodyBuffer().writeBytes(data);
coreMessage.setType(Message.OBJECT_TYPE);
return coreMessage;
} catch (Exception e) {
e.printStackTrace();
return message;
}
}
}

最新更新