Verarbeitung von IBM MQ-Nachrichtenheadern
IBM MQ-Nachrichten können optional Header oder alternative Header zum MQRFH2-Header mit JMS-Eigenschaften enthalten. Anwendungsprogramme von WebSphere Application Server können die Klassen "com.ibm.mq.headers" verwenden, um auf Header in Nachrichten von IBM MQ zuzugreifen und um Header in Nachrichten an IBM MQ zu erstellen.
IBM MQ-Nachrichtenheader
IBM MQ-Nachrichten enthalten immer einen Nachrichtendeskriptor (MQMD). Außerdem können Sie Header mit zusätzlichen Informationen zu den Nachrichten enthalten. So enthalten z. B. Nachrichten an oder von JMS-Anwendungen gewöhnlich einen MQRFH2-Header, der Nachrichteneigenschaften enthält. IBM MQ definiert das Format und die Verwendung einiger Header (z. B. MQRFH2) und ermöglichen Benutzern sowie anderen Softwareanbietern die Definition eigener angepasster Header.
Gewöhnlich ist es nicht erforderlich, dass Anwendungsprogramme IBM MQ-Nachrichtenheader verarbeiten. Die meisten IBM MQ-Anwendungen verwenden gar keine Header oder nur den MQRFH2-Header und die Serviceintegration und die IBM MQ-Messaging-Provider verarbeiten den MQRFH2-Header, wenn Sie mit diesen Anwendungen kommunizieren. Wenn Sie jedoch mit einer IBM MQ-Anwendung kommunizieren, die weitere oder andere Header verwendet oder erstellt, kann Ihre Anwendung von WebSphere Application Server die Klassen "com.ibm.mq.headers" verwenden, um die Header in Nachrichten zu erstellen, die sie sendet, und die Header zu verarbeiten, die empfangenen Nachrichten enthalten sind.
In der IBM MQ-Nachricht befinden sich die Header (sofern vorhanden) am Anfang der Nachricht vor den Nachrichtennutzdaten. Jeder Header enthält Felder, die den folgenden Header bzw. die Nutzdaten, falls keine weiteren Header vorhanden sind, beschreiben. Der MQMD enthält die Felder, die den ersten Header bzw. die Nutzdaten, falls keine Hader vorhanden sind, beschreiben. Der MQMD und der MQRFH2-Header sind normalerweise nicht in einer JMS-Nachricht enthalten. Wenn der Messaging-Provider eine IBM MQ-Nachricht in eine JMS-Nachricht konvertiert, verwendet er Informationen aus dem MQMD und aus dem MQRFH2-Header, um die JMS-Headerfelder und -Eigenschaften zu definieren. Wenn der Messaging-Provider eine JMS-Nachricht in eine IBM MQ-Nachricht konvertiert, verwendet er die JMS-Headerfelder und -Eigenschaften, um den MQMD und den MQRFH2-Header zu erstellen.
Der JMS-Provider behandelt andere Header in IBM MQ-Nachrichten, indem er die IBM MQ-Nachricht in eine JMS-Bytenachricht (BytesMessage) konvertiert und umgekehrt. Die Header erscheinen am Anfang des Nachrichtenhauptteils, gefolgt von den Nutzdaten der IBM MQ-Nachricht (sofern vorhanden). Die Eigenschaft JMS_IBM_Format der JMS-Nachricht gibt das Format der Daten im Nachrichtenhauptteil an (in diesem Fall der erste Header) und die Eigenschaften JMS_IBM_Encoding und JMS_IBM_Character_Set geben die Codierung und die CCSID an.
Verarbeitung von IBM MQ-Nachrichtenheadern in einer JMS-Bytenachricht
Das Paket "com.ibm.mq.headers" enthält Klassen und Schnittstellen, die Sie verwenden können, um IBM MQ-Header im Hauptteil einer JMS-Bytenachricht (BytesMessage) zu parsen und zu bearbeiten. Die Schnittstelle "MQHeader" stellt vielseitig einsetzbare Methoden für den Zugriff auf Headerfelder und zum Lesen und Schreiben von Nachrichteninhalten bereit. Jeder Headertyp hat eine eigene Klasse, die die Schnittstelle "MQHeader" implementiert und Getter- und Setter-Methoden für einzelne Felder hinzufügt. Die Klasse "MQCIH" stellt beispielsweise den Headertyp MQCIH (CICS Bridge) dar. Die Headerklassen führen automatisch die erforderliche Datenkonvertierung durch und können Daten in allen angegebenen numerischen Codierungen und Zeichensätzen (CCSID) lesen oder schreiben.
- MQHeaderIterator funktioniert wie java.util.Iterator. Solange weitere Header in der Nachricht enthalten sind, gibt die Methode next() den Wert true zurück und die Methode nextHeader() bzw. die Methode next() gibt das nächste Headerobjekt zurück.
- MQHeaderList funktioniert wie java.util.List. Wie MQHeaderIterator parst MQHeaderList den Headerinhalt, ermöglicht Ihnen aber zusätzlich, nach bestimmten Headern zu suchen, neue Header hinzuzufügen, vorhandene Header zu entfernen, Headerfelder zu aktualisieren und dann den Headerinhalt zurück in eine Nachricht zu schreiben. Alternativ können Sie eine leere Klasse "MQHeaderList" erstellen, dann mit Headerinstanzen füllen und die Klasse "MQHeaderList" dann einmal oder mehrfach in eine Nachricht schreiben.
Jede Headerklasse implementiert die Schnittstelle "MQHeader", die die Methoden int read (java.io.DataInput message, int encoding, int characterSet) und int write (java.io.DataOutput message, int encoding, int characterSet) bereitstellt. Die Klassen "java.io.DataInputStream" und "java.io.DataOutputStream" implementieren DataInput bzw. DataOutput. Sie können DataInput- und DataOutput-Objekte aus Bytefeldgruppen abrufen, die in JMS-Nachrichten übertragen werden. Dies wird im folgenden Beispiel veranschaulicht, das einen einzelnen MQCIH-Header verarbeitet:
import java.io.*;
import javax.jms.*;
import com.ibm.mq.headers.*;
...
BytesMessage bytesMessage = (BytesMessage) msg; // Vom JMS-Konsumenten empfangene Nachricht
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);
Alternativ können Sie die Klasse "MQHeaderIterator" verwenden, um eine Folge von Headern zu verarbeiten, indem Sie die Zeile, die mit MQCIH cih = new MQCIH beginnt, durch Folgendes ersetzen:
MQHeaderIterator it = new MQHeaderIterator (in,
bytesMessage.getStringProperty("JMS_IBM_Format"),
bytesMessage.getIntProperty("JMS_IBM_Encoding"),
819);
while (it.hasNext()) {
MQHeader item = (MQHeader) it.next();
...
}
In diesem Beispiel wird ein einzelner Header (ein Header des Typs MQCIH) erstellt und einer BytesMessage hinzugefügt:
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);
In diesem Beispiel wird die Klasse "MQHeaderList" verwendet, um einer BytesMessage zwei Header hinzuzufügen:
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 = ... // Kann ein beliebiger Headertyp sein
MQHeader header2 = ... // Kann ein beliebiger Headertyp sein
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);
Verwenden Sie immer die richtigen Werte für die Argumente "encoding" und "characterSet". Geben Sie beim Lesen von Headern die Codierung und die ID des codierten Zeichensatzes (CCSID) an, in denen der Byteinhalt ursprünglich geschrieben wurde. Geben Sie beim Schreiben von Headern die Codierung und die ID des codierten Zeichensatzes an, die Sie erzeugen möchten. Die Datenkonvertierung wird automatisch von den Headerklassen durchgeführt.
Weitere Informationen zu den Klassen "com.ibm.mq.headers"
- MQCIH – Header für CICS-Brücke
- MQIIH – Header für IMS-Informationen
- MQSAPH – SAP-Header
Sie können auch Klassen definieren, die eigene Header darstellen.