IBM MQ メッセージ・ヘッダーの処理方法
IBM MQ メッセージでは、オプションで追加ヘッダーや代替ヘッダーを、JMS プロパティーを含む MQRFH2 ヘッダーに含めることができます。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 を作成して、それにヘッダー・インスタンスを取り込み、メッセージに 1 回または繰り返して書き込むことができます。
すべてのヘッダー・クラスは、メソッド int read (java.io.DataInput message, int encoding, int characterSet) および int write (java.io.DataOutput message, int encoding, int characterSet) を提供する MQHeader インターフェースを実装します。java.io.DataInputStream および java.io.DataOutputStream クラスはそれぞれ implement 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);
あるいは、MQHeaderIterator クラスを使用して、一連のヘッダーを処理し、MQCIH cih = new MQCIH から始まる行を以下で置き換えることができます。
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 クラスを使用して、2 つのヘッダーを 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);
エンコードおよび文字セット引数には常に正しい値を使用してください。ヘッダーを読み取る場合は、始めにバイト・コンテンツの書き込みに使用されたエンコードと CCSID を指定します。ヘッダーを書き込む場合は、作成するエンコードと CCSID を指定します。データ変換は、ヘッダー・クラスによって自動的に実行されます。
com.ibm.mq.headers クラスの詳細
- MQCIH – CICS ブリッジ・ヘッダー
- MQIIH – IMS™ 情報ヘッダー
- MQSAPH – SAP ヘッダー
ユーザー独自のヘッダーを表わすクラスを定義することもできます。