讲师中心 微信公众号
AI工具推荐 视频效率加速

使用JMS发送和接收SWIFT消息:MQRFH2头与消息结构最佳实践

风涛小哥_9570

风涛小哥_9570

发布时间:2025-11-21 17:01:01

|

229人浏览过

|

来源于php中文网

原创

使用JMS发送和接收SWIFT消息:MQRFH2头与消息结构最佳实践

本文深入探讨了在java消息服务(jms)环境中发送和接收swift fileact消息时,如何正确处理mqrfh2头和消息负载。我们将澄清jms与ibm mq集成时mqrfh2头的自动生成机制,并提供通过jms属性设置消息元数据,以及有效传输xml负载和二进制附件的实用指南和代码示例,避免手动构建mqrfh2的常见误区。

引言:JMS与SWIFT FileAct消息传输的挑战

在金融领域,通过JMS(Java Message Service)与IBM MQ集成来发送和接收SWIFT FileAct消息是一种常见的实践。这类消息通常结构复杂,可能包含XML格式的业务负载、用于路由和处理的元数据(通常涉及MQRFH2头),以及作为附件的二进制文件。然而,许多开发者在尝试实现此类功能时,常常会遇到关于如何正确构造消息,特别是如何处理MQRFH2头的困惑。一个常见的误解是,需要手动创建并附加MQRFH2头到JMS消息中,这不仅增加了代码复杂性,还可能导致接收端无法正确解析消息。本教程旨在澄清这一误区,并提供一套基于JMS规范和IBM MQ最佳实践的解决方案。

JMS与IBM MQRFH2头的关系解析

理解JMS与IBM MQRFH2头之间的关系是正确实现消息传输的关键。

核心澄清:MQRFH2头的自动生成 当应用程序使用JMS API与IBM MQ(作为JMS提供者)进行交互时,IBM MQ会自动为JMS消息生成和管理MQRFH2头。这意味着,开发者不应在JMS应用程序中手动构建MQRFH2对象并将其作为消息体的一部分发送。这种做法是错误的,因为它会导致消息体中包含重复或格式不正确的头部信息,使得接收端难以区分真正的消息负载和手动添加的头部字节。

JMS属性映射到MQRFH2的usr文件夹 JMS规范提供了一种通用的方式来为消息设置自定义属性,例如使用JMSProducer.setProperty()或JMSMessage.setStringProperty()等方法。当这些JMS消息通过IBM MQ传输时,IBM MQ会自动将这些自定义属性封装到其内部生成的MQRFH2头的usr文件夹中。因此,所有需要作为元数据传输的信息(如SWIFT FileAct的各种控制参数)都应该通过JMS属性来设置,而不是通过手动构造MQRFH2字节流。

构建和发送结构化JMS消息

为了正确发送包含负载和元数据的JMS消息,我们应遵循以下步骤:

1. 选择合适的消息负载(Payload)类型

根据您的消息内容,选择最合适的JMS消息类型:

  • XML负载: 如果您的主要负载是XML字符串,建议使用javax.jms.TextMessage。JMS提供者会高效地处理文本编码。如果XML中需要嵌入二进制数据(例如,文件内容的Base64编码),请务必使用XML的CDATA块来封装,以避免解析错误。
  • 二进制负载(附件): 对于文件内容(如ZIP文件、图片或其他二进制数据),应使用javax.jms.BytesMessage。BytesMessage允许您直接写入和读取原始字节流。

2. 设置消息元数据(JMS属性)

所有需要作为消息头部信息或控制参数的元数据,都应该通过JMS消息的属性来设置。这些属性将由IBM MQ自动映射到MQRFH2头的usr文件夹中。

示例:发送包含文件附件和元数据的BytesMessage

Java Maven Common
Java Maven Common

Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。

下载

以下代码演示了如何创建一个BytesMessage,设置必要的JMS属性(模拟FileAct的元数据),并将一个文件的内容作为消息负载发送。

import com.ibm.mq.jms.MQConnectionFactory;
import javax.jms.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class SwiftJmsMessageSender {

    /**
     * 发送一个包含文件内容作为负载和JMS属性作为元数据的BytesMessage。
     *
     * @param connectionFactory JMS连接工厂
     * @param destination 目标队列
     * @param filePath 要发送的文件的路径
     * @throws JMSException JMS操作异常
     * @throws IOException 文件读写异常
     */
    public void sendFileActMessage(ConnectionFactory connectionFactory, Destination destination, String filePath) throws JMSException, IOException {
        // 使用JMS 2.0的try-with-resources语法,确保资源自动关闭
        try (JMSContext context = connectionFactory.createContext();
             InputStream inStream = Files.newInputStream(Paths.get(filePath))) {

            JMSProducer producer = context.createProducer();
            BytesMessage bytesMessage = context.createBytesMessage();

            // 1. 设置JMS属性:这些属性将自动映射到MQRFH2头的usr文件夹
            bytesMessage.setStringProperty("OriginatorApplication", "FileActApp");
            bytesMessage.setStringProperty("Requestor", "ou=dept,o=bank,o=swift");
            bytesMessage.setStringProperty("Responder", "ou=target,o=partner,o=swift");
            bytesMessage.setStringProperty("Service", "swift.fileact.transfer");
            bytesMessage.setStringProperty("RequestType", "FileTransfer");
            bytesMessage.setStringProperty("Compression", "Zip"); // 假设文件已压缩
            bytesMessage.setStringProperty("FileName", new File(filePath).getName());
            bytesMessage.setStringProperty("FileReference", "REF-" + System.currentTimeMillis());
            bytesMessage.setJMSCorrelationID("CORRELID-" + System.nanoTime()); // 示例:设置关联ID

            // 2. 将文件内容作为BytesMessage的负载写入
            byte[] buffer = new byte[4096];
            int bytesRead;
            long totalBytesWritten = 0;
            while ((bytesRead = inStream.read(buffer)) != -1) {
                bytesMessage.writeBytes(buffer, 0, bytesRead);
                totalBytesWritten += bytesRead;
            }
            System.out.println("Finished writing " + totalBytesWritten + " bytes into message from file: " + filePath);

            // 3. 发送消息
            producer.send(destination, bytesMessage);
            System.out.println("FileAct message sent successfully with properties and payload to " + destination);

        } catch (JMSException | IOException e) {
            System.err.println("Error sending message: " + e.getMessage());
            throw e; // 重新抛出以便上层处理
        }
    }

    public static void main(String[] args) throws Exception {
        // 示例:配置IBM MQ连接工厂和目标队列
        MQConnectionFactory connectionFactory = new MQConnectionFactory();
        connectionFactory.setHostName("localhost"); // MQ主机名
        connectionFactory.setPort(1414);            // MQ监听端口
        connectionFactory.setQueueManager("QM1");   // 队列管理器名称
        connectionFactory.setChannel("DEV.APP.SVRCONN"); // SVRCONN通道名称

        Queue queue = connectionFactory.createQueue("DEV.QUEUE.1"); // 目标队列名称

        SwiftJmsMessageSender sender = new SwiftJmsMessageSender();
        String testFilePath = "/opt/mq/TC.SB13.0015484631.zip"; // 替换为实际存在的测试文件路径

        // 确保测试文件存在
        if (!Files.exists(Paths.get(testFilePath))) {
            System.err.println("Error: Test file not found at " + testFilePath);
            // 可以创建一个虚拟文件用于测试
            Files.write(Paths.get(testFilePath), "This is a test file content for FileAct.".getBytes());
            System.out.println("Created a dummy test file for demonstration.");
        }

        sender.sendFileActMessage(connectionFactory, queue, testFilePath);
    }
}

接收和解析结构化JMS消息

在接收端,处理JMS消息变得直观,因为JMS API已经为您抽象了MQRFH2头的解析。

1. 识别消息类型

首先,判断接收到的Message对象的实际类型:

  • instanceof TextMessage:处理XML字符串。
  • instanceof BytesMessage:处理二进制数据。

2. 提取消息负载

  • TextMessage: 使用getText()方法直接获取完整的XML字符串。
  • BytesMessage: 使用readBytes()方法循环读取消息体中的二进制数据,直到所有数据被读取完毕。

3. 获取消息元数据

通过JMSMessage接口提供的方法(如getStringProperty(String name)、getIntProperty(String name)等),可以直接访问发送端设置的所有JMS属性。这些属性是透明的,无需手动解析任何头部字节流。

示例:接收包含文件附件和元数据的BytesMessage

以下代码演示了如何接收一个BytesMessage,读取其JMS属性,并将消息负载保存到文件中。

import com.ibm.mq.jms.MQConnectionFactory;
import javax.jms.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Enumeration;

public class SwiftJmsMessageReceiver {

    /**
     * 接收一个FileAct消息,读取其JMS属性和负载,并将负载保存到指定目录。
     *
     * @param connectionFactory JMS连接工厂
     * @param destination 目标队列
     * @param outputDir 保存接收文件的目录
     * @throws JMSException JMS操作异常
     * @throws IOException 文件读写异常
     */
    public void receiveFileActMessage(ConnectionFactory connectionFactory, Destination destination, String outputDir) throws JMSException, IOException {
        try (JMSContext context = connectionFactory.createContext()) {
            JMSConsumer consumer = context.createConsumer(destination);
            System.out.println("Waiting for messages on " + destination + "...");

            Message message = consumer.receive(60000); // 等待最多60秒

            if (message == null) {
                System.out.println("No message

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

相关专题

更多
Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

817

2026.03.03

Swift编程与iOS/macOS应用开发教程合集
Swift编程与iOS/macOS应用开发教程合集

面向苹果生态开发者,系统讲解 Swift 语言核心与 iOS/macOS 应用开发,涵盖 Swift 语法基础、Xcode 开发环境搭建与项目管理、SwiftUI 声明式 UI 开发、UIKit 与 SwiftUI 混合开发策略、Combine 响应式编程框架、数据持久化(SwiftData/Core Data/UserDefaults)、网络请求与 JSON 解析、App 签名/打包/TestFlight 测试与 App Store

1222

2026.06.03

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6239

2023.08.02

pdf怎么转换成xml格式
pdf怎么转换成xml格式

将 pdf 转换为 xml 的方法:1. 使用在线转换器;2. 使用桌面软件(如 adobe acrobat、itext);3. 使用命令行工具(如 pdftoxml)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

4504

2024.04.01

xml怎么变成word
xml怎么变成word

步骤:1. 导入 xml 文件;2. 选择 xml 结构;3. 映射 xml 元素到 word 元素;4. 生成 word 文档。提示:确保 xml 文件结构良好,并预览 word 文档以验证转换是否成功。想了解更多xml的相关内容,可以阅读本专题下面的文章。

5837

2024.08.01

xml是什么格式的文件
xml是什么格式的文件

xml是一种纯文本格式的文件。xml指的是可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。想了解更多相关的内容,可阅读本专题下面的相关文章。

2442

2024.11.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1718

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2644

2023.09.04

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

0

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn