如何处理 IBM MQ 消息头
IBM MQ 消息可以选择性地包括附加头,或者包括 MQRFH2 头(包含 JMS 属性)的备用头。WebSphere® Application Server 应用程序可以使用 com.ibm.mq.headers 类访问来自 IBM MQ 的消息中的头以及构造发送至 IBM MQ 的消息中的头。
IBM MQ 消息头
IBM MQ 消息始终包括消息描述符 (MQMD)。它们还可以包括一些包含其他消息信息的头;例如,往返 JMS 应用程序的消息通常包括 MQRFH2 头,此头包含消息属性。IBM MQ 定义了一些头(例如 MQRFH2)的格式和用法,并且还允许用户和第三方软件提供者定义自己的定制头。
通常,应用程序不必处理 IBM MQ 消息头。大多数 IBM MQ 应用程序要么根本不使用任何头,要么仅使用 MQRFH2 头,并且在您与这些应用程序通信时,服务集成和 IBM MQ 消息传递提供程序会自动处理 MQRFH2 头。但是,如果您正在与使用或者创建附加头或不同头的 IBM MQ 应用程序通信,那么 WebSphere Application Server 应用程序可以使用 com.ibm.mq.headers 类创建它所发送的消息中的头,并且处理它接收到的消息中的头。
在 IBM MQ 消息中,头(如果存在头)位于消息的开头,并且在消息有效内容之前。每个头都包含描述以下头或有效内容(如果没有更多头)的字段;MQMD 包含描述第一个头或有效内容(如果没有头)的字段。MQMD 和 MQRFH2 头通常不出现在 JMS 消息中。当消息传递提供程序将 IBM MQ 消息转换成 JMS 消息时,它使用 MQMD 和 MQRFH2 头中的信息来设置 JMS 头字段和属性。同样,当消息传递提供程序将 JMS 消息转换成 IBM MQ 消息时,它使用 JMS 头字段和属性来构造 MQMD 和 MQRFH2 头。
JMS 提供程序通过将 IBM MQ 消息与 JMS BytesMessage 相互转换来处理 IBM MQ 消息中的其他头;头出现在消息体开头,后跟 IBM MQ 消息有效内容(如果有)。JMS 消息的 JMS_IBM_Format 属性指示消息体(在本例中,为第一个头)中的数据格式,而 JMS_IBM_Encoding 和 JMS_IBM_Character_Set 属性指示其编码和 CCSID。
处理 JMS BytesMessage 中的 IBM MQ 消息头
com.ibm.mq.headers 包中包含可用来解析和处理 JMS BytesMessage 正文中的 IBM MQ 头的类和接口。MQHeader 接口提供一般用途的方法,用于访问头字段和读写消息内容。每种头类型都有自己的类,用于实现 MQHeader 接口以及为各个字段添加 getter 和 setter 方法。例如,MQCIH 类表示 MQCIH(CICS® 网桥)头类型。头类会自动执行任何必需的数据转换,并且可以读写任何指定的数字编码或字符集 (CCSID) 中的数据。
- MQHeaderIterator 的工作方式类似于 java.util.Iterator。由于只要消息中有更多的头,next() 方法就返回 true,而 nextHeader() 或 next() 方法返回下一个头对象。
- MQHeaderList 的工作方式类似于 java.util.List。同 MQHeaderIterator 一样,此辅助类将解析头内容,但它还允许您搜索特定头、添加新的头、移除现有头、更新头字段,然后将头内容写回到消息中。另外,您还可以创建一个空的 MQHeaderList,然后在此辅助类中填充头实例并将其写入消息一次或者重复写入。
每个头类都实现 MQHeader 接口,此接口提供方法 int read (java.io.DataInput message, int encoding, int characterSet) 和 int write (java.io.DataOutput message, int encoding, int characterSet)。java.io.DataInputStream 和 java.io.DataOutputStream 类分别实现 DataInput 和 DataOutput。 您可以从 JMS 消息所携带的字节数组中获取 DataInput 和 DataOutput 对象,如以下示例所示,此示例处理单一 MQCIH 头:
import java.io.*;
import javax.jms.*;
import com.ibm.mq.headers.*;
...
BytesMessage bytesMessage = (BytesMessage) msg; // Message received from JMS consumer
byte[] bytes = new byte [(int) bytesMessage.getBodyLength ()];
bytesMessage.readBytes (bytes);
DataInput in = new DataInputStream (new ByteArrayInputStream (bytes));
MQCIH cih = new MQCIH (in,
bytesMessage.getIntProperty("JMS_IBM_Encoding"),
819);
另外,您也可以通过将以 MQCIH cih = new MQCIH 开头的行替换为以下内容,从而使用 MQHeaderIterator 类来处理头序列:
MQHeaderIterator it = new MQHeaderIterator (in,
bytesMessage.getStringProperty("JMS_IBM_Format"),
bytesMessage.getIntProperty("JMS_IBM_Encoding"),
819);
while (it.hasNext()) {
MQHeader item = (MQHeader) it.next();
...
}
此示例创建单一头(MQCIH 类型的头)并将其添加到 BytesMessage 中:
import java.io.*;
import javax.jms.*;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.headers.*;
...
MQCIH header = new MQCIH();
ByteArrayOutputStream out = new ByteArrayOutputStream ();
header.write (new DataOutputStream (out), CMQC.MQENC_NATIVE, 819);
byte[] bytes = out.toByteArray ();
BytesMessage newMsg = origSes.createBytesMessage();
newMsg.writeBytes(bytes);
此示例使用 MQHeaderList 类将两个头添加到 BytesMessage 中:
import java.io.*;
import javax.jms.*;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.headers.*;
...
byte[] outheaders = null;
byte[] outbody = ...
try {
MQHeaderList it = new MQHeaderList ();
MQHeader header1 = ... // Could be any header type
MQHeader header2 = ... // Could be any header type
ByteArrayOutputStream out = new ByteArrayOutputStream ();
DataOutput dout = new DataOutputStream(out);
it.add(header1);
it.add(header2);
it.write(dout);
outheaders = out.toByteArray();
} catch (Exception e) {
System.out.println("error generating MQ message headers : " + e);
}
BytesMessage newMsg = origSes.createBytesMessage();
newMsg.writeBytes(outheaders);
newMsg.writeBytes(bytes);
newMsg.setStringProperty("JMS_IBM_Format", "MQCICS");
newMsg.setIntProperty("JMS_IBM_Encoding", CMQC.MQENC_NATIVE);
newMsg.setIntProperty("JMS_IBM_Character_Set", 819);
请始终对 encoding 和 characterSet 参数使用正确的值。当您读取头时,请指定最初写入字节内容时所使用的编码和 CCSID。写入头时,请指定要生成的编码和 CCSID。数据转换由头类自动执行。
关于 com.ibm.mq.headers 类的更多信息
- MQCIH - CICS 网桥头
- MQIIH - IMS™ 信息头
- MQSAPH - SAP 头
您也可以定义表示您自己的头的类。