简体   繁体   中英

Sending and Receiving SWIFT-messages with JMS

I am trying currently to send and receive messages on SWIFT FileAct. The current implementation is based on JMS. The requirement is, that I need to send an xml-message as payload, an XML-header that according to the information I got is supposed to be an RFH2-header and possible attachment-files (hence FileAct).

I have a working connection to the Queue-manager and am able to send and read general text- or byte-messages. The problem is, that the format does not seem to be correct, in terms of the RFH2-header and the payload (and later possible attachments). So when I read the message (that I can send myselve) I am just working on a stream of bytes. The problem is, how to say, when what part of the message is what (header/payload/attachments), since its just a stream of bytes.

I can add some blocks of code. And two screenshots from the console when the operations are done. Maybe you can see something, that I am missing?

public void sendAByteMessage(JmsConnectionFactory connectionFactory, Destination destination) {
  String ifCobaString = "IF_COBA";
  String filename;
  FileInputStream inStream;
  BytesMessage bytesMessage;
  int bytesRead;
  int bytesTotalSize = 0;
  byte[] buf1 = new byte[64];

    // write RFH2-Header
    MQRFH2 mqrfh2 = new MQRFH2();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    mqrfh2.setEncoding(CMQC.MQENC_NATIVE);
    mqrfh2.setCodedCharSetId(CMQC.MQCCSI_INHERIT);
    mqrfh2.setFormat(CMQC.MQFMT_NONE);
    mqrfh2.setFlags(0);
    mqrfh2.setNameValueCCSID(1208);

    mqrfh2.setFieldValue(ifCobaString, "OriginatorApplication", "data");
    mqrfh2.setFieldValue(ifCobaString, "Requestor", "ou=data,o=data,o=swift");
    mqrfh2.setFieldValue(ifCobaString, "Responder", "ou=data,o=data,o=swift");
    mqrfh2.setFieldValue(ifCobaString, "Service", "swift.data");
    mqrfh2.setFieldValue(ifCobaString, "RequestType", "data");
    mqrfh2.setFieldValue(ifCobaString, "Compression", "Zip");
    mqrfh2.setFieldValue(ifCobaString, "FileName", "data.zip");
    mqrfh2.setFieldValue(ifCobaString, "FileReference", "data.zip");

    mqrfh2.write(new DataOutputStream(out), CMQC.MQENC_NATIVE, 819);

    byte[] bytesHeader = out.toByteArray();

    // set the input file to be send
    filename = "/opt/mq/TC.SB13.0015484631.zip"; // just a random file that I am trying to send over the message
    inStream = new FileInputStream(filename);

    JMSContext producerContext = connectionFactory.createContext();
    JMSProducer producer = producerContext.createProducer();
    bytesMessage = producerContext.createBytesMessage();

    // add RHF2-header to the message
    bytesMessage.writeBytes(bytesHeader);

    // add payload to the message
    while ((bytesRead = inStream.read(buf1)) != -1) {
      bytesMessage.writeBytes(buf1, 0, bytesRead);
      bytesTotalSize += bytesRead;
      System.out.println("Writing " + bytesRead + " bytes into message..");
    }

    System.out.println("Finished writing " + bytesTotalSize + " bytes into message!");

    producer.send(destination, bytesMessage);
    producerContext.close();
    inStream.close();

}

And this is the code for reading it. The FileOutputStream also creates the WRITE.zip-file successfully, but then we don't have any information about the header. Its kind of lost-in-translation.

I am not sure if we need to for example first read x bytes that are the header and then the rest what is the file. But then I am confused because here we use the entire length of the message for the file, as there is nothing additional for the header. It's a bit confusing..


// The message is sent as a Message object, so we must determine its type
if (message instanceof TextMessage) {
  System.out.println("-- reading TEXT-message..");
  TextMessage textMessage = (TextMessage) message;

  try {
    System.out.println("-- MyMessageListener received message with payload: " + textMessage.getText());
  } catch (JMSException jmse) {
    System.out.println("JMS Exception in MyMessageListener class (TextMessage)!");
    System.out.println(jmse.getLinkedException());
  }

} else if (message instanceof BytesMessage) {
  System.out.println("-- reading BYTE-message..");
  BytesMessage bytesMessage = (BytesMessage) message;

  try {
    int textLength = (int) bytesMessage.getBodyLength();
    byte[] textBytes = new byte[textLength];
    bytesMessage.readBytes(textBytes, textLength);

    // Save file
    FileOutputStream fos = new FileOutputStream("/opt/mq/WRITE.zip");
    fos.write(textBytes);
    fos.close();

    // Show content of file
    String content = new String(textBytes);
    System.out.println(content);

I think someone gave you some incorrect information regarding MQRFH2 messages.

If your application is a JMS application, then you are totally on the wrong path.

IBM MQ treats a JMS message as an MQRFH2 message. So, when you send a JMS application, you do not create an MQRFH2 message. IBM MQ does it automatically for you.

Secondly, you talk about XML messages but nowhere in your code do I see anything about XML or CDATA. If you want to send binary data as part of your XML message, then CDATA must be used.

If you want properties for the message, then you need to put them in the "usr" folder for JMS application. If you want to use a different folder then you need to use a regular Java application (non-JMS) and of course, then build an MQRFH2 header.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM