You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于JMS收发SWIFT FileAct消息的格式问题求助

问题根源

你当前的错误在于把RFH2头的字节直接写入了BytesMessage的消息体中,导致头和payload合并成连续字节流,接收时无法区分。RFH2是IBM MQ的消息头结构,不属于消息体内容,应该通过MQ API正确设置为消息的头部属性,而非消息体的一部分。

解决方案步骤

1. 修正发送端代码:正确设置RFH2头

使用IBM MQ JMS的扩展类MQBytesMessage访问底层MQMessage,将RFH2作为消息头附加,而非写入消息体:

public void sendSwiftFileActMessage(JmsConnectionFactory connectionFactory, Destination destination) throws Exception {
    String ifCobaString = "IF_COBA";
    String filename = "/opt/mq/TC.SB13.0015484631.zip";
    
    // 构建RFH2头
    MQRFH2 mqrfh2 = new MQRFH2();
    mqrfh2.setEncoding(CMQC.MQENC_NATIVE);
    mqrfh2.setCodedCharSetId(CMQC.MQCCSI_INHERIT);
    mqrfh2.setFormat(CMQC.MQFMT_NONE);
    mqrfh2.setFlags(0);
    mqrfh2.setNameValueCCSID(1208);

    // 设置SWIFT FileAct相关字段
    mqrfh2.setFieldValue(ifCobaString, "OriginatorApplication", "data");
    mqrfh2.setFieldValue(ifCobaString, "Requestor", "ou=data,o=data,o=swift");
    mqrfh2.setFieldValue(ifCobaString, "Responder", "ou=data,o=data,o=swift");
    mqrfh2.setFieldValue(ifCobaString, "Service", "swift.data");
    mqrfh2.setFieldValue(ifCobaString, "RequestType", "data");
    mqrfh2.setFieldValue(ifCobaString, "Compression", "Zip");
    mqrfh2.setFieldValue(ifCobaString, "FileName", "data.zip");
    mqrfh2.setFieldValue(ifCobaString, "FileReference", "data.zip");

    // 创建JMS上下文和消息
    try (JMSContext producerContext = connectionFactory.createContext();
         FileInputStream inStream = new FileInputStream(filename)) {
        
        MQBytesMessage bytesMessage = (MQBytesMessage) producerContext.createBytesMessage();
        MQMessage mqMessage = bytesMessage.getMQMessage();
        
        // 将RFH2头附加到MQMessage
        mqrfh2.write(mqMessage);
        
        // 写入payload/附件到消息体
        byte[] buf = new byte[4096];
        int bytesRead;
        while ((bytesRead = inStream.read(buf)) != -1) {
            bytesMessage.writeBytes(buf, 0, bytesRead);
        }

        // 设置消息格式为RFH2,告知MQ这是带扩展头的消息
        mqMessage.format = CMQC.MQFMT_RFH2;
        
        // 发送消息
        producerContext.createProducer().send(destination, bytesMessage);
    }
}

2. 修正接收端代码:解析RFH2头并提取payload

接收时先解析RFH2头,再读取剩余消息体作为payload/附件:

// 处理接收到的消息
if (message instanceof MQBytesMessage) {
    System.out.println("-- reading MQ BYTE-message with RFH2 header..");
    MQBytesMessage bytesMessage = (MQBytesMessage) message;
    MQMessage mqMessage = bytesMessage.getMQMessage();
    
    try {
        // 解析RFH2头,读取后指针自动定位到消息体起始处
        MQRFH2 mqrfh2 = new MQRFH2();
        mqrfh2.read(mqMessage);
        
        // 验证RFH2字段
        System.out.println("OriginatorApplication: " + mqrfh2.getFieldValue("IF_COBA", "OriginatorApplication"));
        System.out.println("FileName: " + mqrfh2.getFieldValue("IF_COBA", "FileName"));
        
        // 读取消息体内容
        long bodyLength = mqMessage.getMessageLength() - mqMessage.getPosition();
        byte[] payloadBytes = new byte[(int) bodyLength];
        mqMessage.readFully(payloadBytes);
        
        // 保存附件文件
        try (FileOutputStream fos = new FileOutputStream("/opt/mq/WRITE.zip")) {
            fos.write(payloadBytes);
        }
        
        System.out.println("Successfully extracted RFH2 header and saved payload as file.");
        
    } catch (Exception e) {
        e.printStackTrace();
    }
} else if (message instanceof TextMessage) {
    // 原有TextMessage处理逻辑
    System.out.println("-- reading TEXT-message..");
    TextMessage textMessage = (TextMessage) message;
    try {
        System.out.println("-- MyMessageListener received message with payload: " + textMessage.getText());
    } catch (JMSException jmse) {
        System.out.println("JMS Exception in MyMessageListener class (TextMessage)!");
        System.out.println(jmse.getLinkedException());
    }
}
关键说明
  • RFH2的正确位置:RFH2是MQ的扩展消息头,必须通过MQRFH2.write(mqMessage)附加到头部区域,而非写入消息体。读写后消息指针会自动跳转到消息体起始位置。
  • 消息格式标识:发送时必须设置mqMessage.format = CMQC.MQFMT_RFH2,确保MQ和接收端识别带RFH2头的消息。
  • 类型转换:需将JMS标准BytesMessage转为IBM MQ扩展的MQBytesMessage,才能访问底层MQMessage进行头操作。

内容的提问来源于stack exchange,提问作者the_villian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:15:38