如何在ActiveMQ Artemis中通过Transformer修改JMS TextMessage消息体
问题分析与解决方案
1. 排查Transformer实现问题
你的自定义Transformer大概率只处理了消息属性,未对消息体做修改。要修改消息体,需在transform方法中操作ServerMessage的payload缓冲区。
正确的Transformer实现示例:
import org.apache.activemq.artemis.core.server.transformer.Transformer; import org.apache.activemq.artemis.core.server.ServerMessage; import org.apache.activemq.artemis.api.core.SimpleString; public class MyCustomTransformer implements Transformer { @Override public ServerMessage transform(ServerMessage message) { // 添加自定义属性(你已实现的部分) message.putStringProperty(new SimpleString("customProp"), new SimpleString("modifiedValue")); // 修改消息体 byte[] originalBody = message.getBodyBuffer().copy().readBytes(); String modifiedContent = new String(originalBody) + " [TRANSFORMED]"; message.getBodyBuffer().clear(); message.getBodyBuffer().writeBytes(modifiedContent.getBytes()); return message; } }
如果是ObjectMessage或BytesMessage等特殊类型,需对应处理序列化或字节流逻辑。
2. 配置Divert匹配需求
根据你的目标选择对应模式:
场景1:保留原始消息,转发修改后的副本(默认模式)
原队列消息不变,转发队列获取修改后的内容,配置如下:
<divert name="myDivert"> <address>originalQueueAddress</address> <forwarding-address>forwardingQueueAddress</forwarding-address> <transformer-class-name>com.yourpackage.MyCustomTransformer</transformer-class-name> <exclusive>false</exclusive> <!-- copy模式,默认值可省略 --> </divert>
场景2:修改原始消息并转移到转发队列
原队列不再保留消息,转发队列拿到修改后的版本,需启用exclusive模式:
<divert name="myDivert"> <address>originalQueueAddress</address> <forwarding-address>forwardingQueueAddress</forwarding-address> <transformer-class-name>com.yourpackage.MyCustomTransformer</transformer-class-name> <exclusive>true</exclusive> <!-- move模式,原地址无消息残留 --> </divert>
3. 修正消息接收逻辑
确保ReceiveFrwd.java正确读取消息体:
ClientMessage forwardedMsg = frwdConsumer.receive(); // 读取修改后的消息体 String bodyContent = forwardedMsg.getBodyBuffer().readString(); System.out.println("转发队列消息体:" + bodyContent); // 读取自定义属性 String customProp = forwardedMsg.getStringProperty("customProp"); System.out.println("自定义属性:" + customProp); forwardedMsg.acknowledge();
常见避坑点
- 修改消息体前要清空缓冲区:直接写入新内容会覆盖部分原始数据,需调用
clear()重置缓冲区后再写入。 - 注意JMS消息类型与核心
ServerMessage的对应:比如TextMessage对应核心消息的TYPE_TEXT类型,处理时要匹配类型逻辑。
内容的提问来源于stack exchange,提问作者Prabhu
相关产品推荐
相关产品推荐

