Como processar cabeçalhos das mensagens do IBM MQ
Opcionalmente, as mensagens do IBM MQ podem incluir cabeçalhos adicionais ou cabeçalhos alternativos no cabeçalho do MQRFH2, que contém propriedades do JMS. Os programas de aplicativos do WebSphere Application Server podem usar as classes com.ibm.mq.headers para acessar cabeçalhos em mensagens do IBM MQ e construir cabeçalhos em mensagens para o IBM MQ.
Cabeçalhos das mensagens do IBM MQ
As mensagens do IBM MQ incluem sempre um descritor de mensagens (MQMD). Elas também podem incluir cabeçalhos contendo informações adicionais sobre as mensagens; por exemplo, mensagens de ou para aplicativos JMS incluem, geralmente, um cabeçalho MQRFH2 que contém propriedades da mensagem. O IBM MQ define o formato e o uso de alguns cabeçalhos (por exemplo, MQRFH2) e também permite que usuários e provedores de software de terceiros definam seus próprios cabeçalhos customizados.
Geralmente, não é necessário que os programas de aplicativos processem cabeçalhos das mensagens do IBM MQ. A maioria dos aplicativos IBM MQ não usa cabeçalhos, ou usa somente o cabeçalho MQRFH2, e a integração de serviço e os provedores de sistemas de mensagens do IBM MQ processarão automaticamente o cabeçalho MQRFH2 quando você estiver se comunicando com esses aplicativos. No entanto, se você estiver se comunicando com um aplicativo IBM MQ que usa ou cria cabeçalhos adicionais ou diferentes, em seguida, o aplicativo WebSphere Application Server poderá usar as classes com.ibm.mq.headers para criar os cabeçalhos em mensagens enviadas, e processá-las em mensagens recebidas.
Na mensagem do IBM MQ, os cabeçalhos (se houver) são o início da mensagem, antes da carga útil da mensagem. Cada cabeçalho contém campos que descrevem o cabeçalho seguinte, ou a carga útil, se não houver mais cabeçalhos; o MQMD contém os campos que descrevem o primeiro cabeçalho, ou a carga útil, se não houver cabeçalhos. O cabeçalho MQMD e o cabeçalho MQRFH2 não aparecem normalmente em uma mensagem JMS. Quando o provedor de sistemas de mensagens converter uma mensagem do IBM MQ em uma mensagem do JMS, ele usará informações dos cabeçalhos MQMD e MQRFH2 para configurar campos e propriedades do cabeçalho do JMS. Da mesma forma, quando o provedor de sistemas de mensagens converter uma mensagem do JMS em uma mensagem do IBM MQ, ele usará os campos e as propriedades do cabeçalho do JMS para construir os cabeçalhos MQMD e MQRFH2.
O provedor JMS manipula outros cabeçalhos em mensagens do IBM MQ, convertendo a mensagem do IBM MQ para e a partir de uma BytesMessage JMS; os cabeçalhos aparecem no início do corpo da mensagem, seguidos pela carga útil da mensagem (se houver) do IBM MQ. A propriedade JMS_IBM_Format da mensagem do JMS indica o formato dos dados no corpo da mensagem (neste caso, o primeiro cabeçalho) e as propriedades JMS_IBM_Encoding e JMS_IBM_Character_Set indicam sua codificação e CCSID.
Processando cabeçalhos das mensagens do IBM MQ em uma BytesMessage JMS
O pacote com.ibm.mq.headers contém classes e interfaces que podem ser usadas para analisar e manipular cabeçalhos do IBM MQ no corpo de uma BytesMessage JMS. A interface MQHeader fornece métodos de uso geral para acessar campos de cabeçalho e para ler e gravar conteúdo da mensagem. Cada tipo de cabeçalho possui sua própria classe que implementa a interface MQHeader e inclui métodos getter e setter para campos individuais. Por exemplo, a classe MQCIH representa o tipo de cabeçalho MQCIH (Ponte do CICS). As classes de cabeçalho executam qualquer conversão de dados necessária automaticamente, e podem ler ou gravar dados em qualquer codificação numérica ou conjunto de caracteres (CCSID) especificado.
- MQHeaderIterator funciona como uma java.util.Iterator. Enquanto houver mais cabeçalhos na mensagem, o método next() retornará true, e o método nextHeader() ou next() retornará o próximo objeto do cabeçalho.
- MQHeaderList funciona como um java.util.List. Como MQHeaderIterator, ela analisa o conteúdo do cabeçalho, mas também permite procurar cabeçalhos específicos, incluir novos cabeçalhos, remover cabeçalhos existentes, atualizar campos de cabeçalho e, em seguida, gravar o conteúdo do cabeçalho de volta em uma mensagem. Alternativamente, é possível criar uma MQHeaderList vazia e, em seguida, preenchê-la com instâncias de cabeçalho e gravá-la em uma mensagem uma vez ou repetidamente.
Cada classe de cabeçalho implementa a interface MQHeader, que fornece os métodos int read (java.io.DataInput message, int encoding, int characterSet) e int write (java.io.DataOutput message, int encoding, int characterSet). As classes java.io.DataInputStream e java.io.DataOutputStream implementam DataInput e DataOutputm respectivamente. É possível obter objetos DataInput e DataOutput de matrizes de byte transportadas em mensagens JMS, como no seguinte exemplo, que processa um único cabeçalho MQCIH:
import java.io.*;
import javax.jms.*;
import com.ibm.mq.headers.*;
...
BytesMessage bytesMessage = (BytesMessage) msg; // Mensagem recebida do consumidor JMS
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);
Alternativamente, é possível usar a classe MQHeaderIterator para processar uma sequência de cabeçalhos, substituindo a linha iniciada com MQCIH cih = new MQCIH por:
MQHeaderIterator it = new MQHeaderIterator (in,
bytesMessage.getStringProperty("JMS_IBM_Format"),
bytesMessage.getIntProperty("JMS_IBM_Encoding"),
819);
while (it.hasNext()) {
MQHeader item = (MQHeader) it.next();
...
}
Este exemplo cria um único cabeçalho (um cabeçalho do tipo MQCIH) e o inclui em uma 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);
Este exemplo usa a classe MQHeaderList para incluir dois cabeçalhos em uma 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 = ... // Poderia ser qualquer tipo de cabeçalho
MQHeader header2 = ... // Poderia ser qualquer tipo de cabeçalho
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);
Sempre use os valores corretos para os argumentos de codificação e conjunto de caracteres. Ao ler cabeçalhos, especifique a codificação e o CCSID com o qual o conteúdo de byte foi gravado originalmente. Ao gravar cabeçalhos, especifique a codificação e o CCSID que você deseja produzir. A conversão de dados é executada automaticamente pelas classes de cabeçalho.
Mais Informações sobre as Classes com.ibm.mq.headers
- MQCIH – Cabeçalho de Ponte do CICS
- MQIIH – Cabeçalho de Informações do IMS
- MQSAPH – Cabeçalho do SAP
Também é possível definir classes representando seus próprios cabeçalhos.