如何从Solace的InboundMessage中读取二进制附件?
解决Python发消息、Java消费时提取二进制附件的问题
1. 识别二进制附件格式
你提供的二进制附件是Python Pickle序列化的数据,开头的80 04是Pickle协议版本4的标识。反序列化后对应model.batch.Batch类实例,其中name属性值为hello world!。
2. Java端提取InboundMessage中的二进制附件
根据使用的消息框架不同,提取方式略有差异,以下是常见场景的处理代码:
场景1:Spring Integration的InboundMessage
附件通常存储在消息headers或作为payload的一部分:
// 假设inboundMsg为接收的InboundMessage实例 // 从headers中获取附件 byte[] attachmentBytes = (byte[]) inboundMsg.getHeaders().get("attachmentKey"); // 若附件是MultipartFile类型的payload if (inboundMsg.getPayload() instanceof MultipartFile) { MultipartFile file = (MultipartFile) inboundMsg.getPayload(); byte[] attachmentBytes = file.getBytes(); }
场景2:JMS BytesMessage
如果是JMS的BytesMessage类型消息:
BytesMessage bytesMsg = (BytesMessage) message; byte[] attachmentBytes = new byte[(int) bytesMsg.getBodyLength()]; bytesMsg.readBytes(attachmentBytes);
3. 解析Pickle格式的二进制数据
由于附件是Python Pickle序列化对象,Java端需要专用库解析:
- 使用
pickle4j库(Maven引入):
<dependency> <groupId>com.github.romix.akka</groupId> <artifactId>pickle4j</artifactId> <version>0.6.1</version> </dependency>
解析代码:
import com.romix.pickle.PickleException; import com.romix.pickle.Unpickler; import java.io.ByteArrayInputStream; import java.util.Map; // 假设已获取attachmentBytes二进制数据 ByteArrayInputStream bis = new ByteArrayInputStream(attachmentBytes); Unpickler unpickler = new Unpickler(bis); try { Object result = unpickler.load(); // Pickle自定义对象在Java中会转为Map if (result instanceof Map) { Map<String, Object> batchMap = (Map<String, Object>) result; String name = (String) batchMap.get("name"); System.out.println("提取到name属性:" + name); // 输出hello world! } } catch (PickleException e) { e.printStackTrace(); }
- 也可使用JPype调用Python的pickle模块解析,适合处理更复杂的自定义对象。
4. 跨语言序列化优化建议
如果后续想避免跨语言序列化的兼容性问题,建议Python端改用JSON、Protobuf等跨语言通用的序列化格式,Java端处理会更简便。
内容的提问来源于stack exchange,提问作者Dipak Jadhav
相关产品推荐
相关产品推荐

