Build it yourself

To build, test and run the MQ custom bindings sample, follow these steps:

Creating the Header and Body Business Objects

Before writing the data binding code, we need to define the business objects for the message header and the message body, and the interface for a two-way operation.

  1. Create a library project called Library to store the objects we will create below.
  2. For the body of the message, define the following Customer and Address business objects:
  3. For the header of the message, define the following CustomMQHeader business object:
  4. Create an interface called ICustomer with a two-way operation as follows:


Creating the MQ Header Data Binding

To create the data binding code:

  1. Define a Java project called CustomMQDataBindingSamples. You will need to add the following to the build path for this project:
    • com.ibm.mq.jar - this will be in the Java/lib directory under your MQ installation
    • A reference to a WebSphere ESB 6.1 or Process Server 6.1 runtime definition
  2. For the MQ header data binding, create a Java class called CustomMQHeaderDataBindingSample in a package called com.ibm.wesb.sample.MQDataBinding. This class needs to implement the com.ibm.websphere.sca.mq.data.MQHeaderDataBinding interface.


    Note: do not use the default package as it has been known to cause problems.

    The content of this class is shown below:

    package com.ibm.wesb.sample.MQDataBinding;
    
    import java.io.IOException;
    import com.ibm.mq.MQC; import com.ibm.mq.data.MQDataInputStream; import com.ibm.mq.data.MQDataOutputStream; import com.ibm.websphere.bo.BOFactory; import com.ibm.websphere.bo.BOXMLSerializer; import com.ibm.websphere.sca.ServiceManager; import com.ibm.websphere.sca.mq.data.MQHeaderDataBinding; import commonj.connector.runtime.DataBindingException; import commonj.sdo.DataObject;
    public class CustomMQHeaderDataBindingSample implements MQHeaderDataBinding { private static final long serialVersionUID = 1L; private DataObject dataObject; // stores the current header data object private int nextCCSID; // stores the CCSID for the next part of the message private int nextEncoding; // stores the encoding for the next part of the message private String nextFormat; // stores the format for the next part of the message
    /** * Returns the CCSID for the next part of the message. */ public int getNextCCSID() { System.out.println("CustomMQHeaderDataBindingSample - getNextCCSID() : "); return nextCCSID; }
    /** * Returns the encoding for the next part of the message. */ public int getNextEncoding() { System.out.println("CustomMQHeaderDataBindingSample - getNextEncoding() : "); return nextEncoding; }
    /** * Returns the format for the next part of the message. */ public String getNextFormat() { System.out.println("CustomMQHeaderDataBindingSample - getNextFormat() : "); return nextFormat; }
    /** * Check if this is a recognised format. * @param arg0 The format being checked * @return true if the format is recognised, false otherwise */ public boolean isSupportedFormat(String arg0) { System.out.println("CustomMQHeaderDataBindingSample - isSupportedFormat() : arg0 = " + arg0); return (arg0 != null && arg0.trim().equals("WESBSAMP")); }
    /** * Read from the input stream and constructs a data object for the * custom MQ header. * @param arg0 - Format of the MQDataInputStream * @param arg1 - Data read from the MQ Queue * Reads the input stream and construct the custom MQ header data object. * @throws IOException */ public void read(String arg0, MQDataInputStream arg1) throws IOException { System.out.println("CustomMQHeaderDataBindingSample - read() : arg0 = " + arg0); System.out.println("CustomMQHeaderDataBindingSample - read() : arg1 = " + arg1); // Get the first 4 character and check if we've the correct header. String strucID = arg1.readMQCHAR4(); // Throw an IOException if the header is wrong. if(!strucID.equals("WESB")) throw new IOException("Malformed custom MQ sample header."); int strucLength = arg1.readMQINT32(); // Next four bytes in the input stream contain the length of this header String msgType = arg1.readMQCHAR4(); // Message type (DELI=delimited, FXLN=Fixed Length, NAVA=Named Value) String msgOption1 = arg1.readMQCHAR4(); // Message option 1 for delimiter character in DELI and length in FXLN String msgOption2 = arg1.readMQCHAR4(); // Message option 2 for padding character in FXLN
    setNextCCSID(arg1.getCCSID()); // Copy the CCSID for the next part of the message setNextEncoding(arg1.getEncoding()); // Copy the encoding for the next part of the message setNextFormat(MQC.MQFMT_STRING); // The next part of the message should be the actual dataObject
    // Create a temporary data object for the MQ header. BOFactory boFactory = (BOFactory) new ServiceManager().locateService("com/ibm/websphere/bo/BOFactory"); DataObject bo = boFactory.create("http://Library", "CustomMQHeader"); bo.setString("strucID", strucID); bo.setInt("strucLength", strucLength); bo.setString("msgType", msgType); bo.setString("msgOption1", msgOption1); bo.setString("msgOption2", msgOption2); try { setDataObject(bo); } catch (DataBindingException e) { e.printStackTrace(); } }
    /** * Sets the CCSID for the next part of the message. */ public void setNextCCSID(int arg0) { System.out.println("CustomMQHeaderDataBindingSample - setNextCCSID() : arg0 = " + arg0); nextCCSID = arg0; }
    /** * Sets the encoding for the next part of the message. */ public void setNextEncoding(int arg0) { System.out.println("CustomMQHeaderDataBindingSample - setNextEncoding() : arg0 = " + arg0); nextEncoding = arg0; }
    /** * Sets the format for the next part of the message. */ public void setNextFormat(String arg0) { System.out.println("CustomMQHeaderDataBindingSample - setNextFormat() : arg0 = " + arg0); nextFormat = arg0; }
    /** * * Writes the Custom MQ header data object into the output stream. */ public void write(String arg0, MQDataOutputStream arg1) throws IOException { System.out.println("CustomMQHeaderDataBindingSample - write() : arg0 = " + arg0); System.out.println("CustomMQHeaderDataBindingSample - write() : arg1 = " + arg1); arg1.writeMQCHAR4(dataObject.getString("strucID")); arg1.writeMQINT32(dataObject.getInt("strucLength")); arg1.writeMQCHAR4(dataObject.getString("msgType")); arg1.writeMQCHAR4(dataObject.getString("msgOption1")); arg1.writeMQCHAR4(dataObject.getString("msgOption2")); }
    /** * Return the message header data object. */ public DataObject getDataObject() throws DataBindingException { System.out.println("CustomMQHeaderDataBindingSample - getDataObject() :"); return dataObject; }
    /** * Sets the message header data object. */ public void setDataObject(DataObject arg0) throws DataBindingException { try { System.out.println("CustomMQHeaderDataBindingSample - setDataObject() : arg0 = "); BOXMLSerializer boSer = (BOXMLSerializer)new ServiceManager().locateService("com/ibm/websphere/bo/BOXMLSerializer"); boSer.writeDataObject(arg0, arg0.getType().getURI(), arg0.getType().getName(), System.out); } catch (IOException e) { e.printStackTrace(); } this.dataObject = arg0; } }

Creating the MQ Body Data Binding

For the MQ body data binding, create a Java class called CustomMQBodyDataBindingSample in the com.ibm.wesb.sample.MQDataBinding package. It will need to implement the com.ibm.websphere.sca.mq.data.MQBodyDataBinding interface.

The content of this class is shown below:

package com.ibm.wesb.sample.MQDataBinding;

import java.io.IOException; import java.util.List;
import com.ibm.mq.MQException; import com.ibm.mq.data.MQDataInputStream; import com.ibm.mq.data.MQDataOutputStream; import com.ibm.websphere.bo.BOFactory; import com.ibm.websphere.bo.BOXMLSerializer; import com.ibm.websphere.sca.ServiceManager; import com.ibm.websphere.sca.mq.data.MQBodyDataBinding; import com.ibm.websphere.sca.mq.structures.MQMD; import commonj.connector.runtime.DataBindingException; import commonj.sdo.DataObject;
public class CustomMQBodyDataBindingSample implements MQBodyDataBinding { private static final long serialVersionUID = 1L; // This stores the names of each of the Customer business object elements String names[] = {"id", "firstName", "lastName", "address", "id", "street", "city", "state", "zip"}; DataObject dataObject; // Data object for storing the custom MQ body business object.
/* * Method not being use in this sample. * This method is called before the read and contains the MQ format string * indentifying the body format. It is also called before a write, and contains * the MQ format string described in the SCA header. * (non-Javadoc) * @see com.ibm.websphere.sca.mq.data.MQBodyDataBinding#getFormat() */ public String getFormat() { System.out.println("CustomMQBodyDataBindingSample - getFormat() :"); return null; }
/* * State whether or not this data object is to be treated as a business exception. * This method is not use in this sample except to return the default value of false. * (non-Javadoc) * @see com.ibm.websphere.sca.mq.data.MQBodyDataBinding#isBusinessException() */ public boolean isBusinessException() { System.out.println("CustomMQBodyDataBindingSample - isBusinessException() :"); return false; }
/** * Reads the incoming MQ message data and convert it into a data object. * The message header indicates the format of the incoming message, more * specifically, the format is dependent upon the msgType element of the * message header, which can be one of the following: * * DELI * The incoming message is a string of elements separate by a delimiter.
* The delimiter is specified in the message header as msgOption1. * FXLN * The incoming message is a string of fixed length elements, padded * out by a padding character if required.
* The element length and padding character are specified in the message * header as msgOption1 and msgOption2 respectively. * * @param arg0 - MQ message descriptor of the incoming data * @param arg1 - List of MQ headers of the incoming data * @param arg2 - The input stream containing the incoming data */ public void read(MQMD arg0, List arg1, MQDataInputStream arg2) throws IOException { System.out.println("CustomMQBodyDataBindingSample - read() : arg0 = " + arg0); System.out.println("CustomMQBodyDataBindingSample - read() : arg1 = " + arg1.toString()); System.out.println("CustomMQBodyDataBindingSample - read() : arg2 = " + arg2); String str = arg2.readUTF().toString(); // Read all of the data from the data stream into a string.
BOFactory boFactory = (BOFactory) new ServiceManager().locateService("com/ibm/websphere/bo/BOFactory"); // Create a temporary data object for the customer business object. DataObject customerObj = boFactory.create("http://Library", "Customer"); // Get the MQ header from the list in arg1. DataObject MQHeader = (DataObject) arg1.get(0); // Get the custom MQ header data object. DataObject CustomMQHeader = MQHeader.getDataObject("value"); String msgType = CustomMQHeader.getString("msgType"); if(msgType.compareTo("DELI") == 0) { customerObj = readDelimited(str, CustomMQHeader.getString("msgOption1").trim()); } if(msgType.compareTo("FXLN") == 0) { try { customerObj = readFixedLength(str, Integer.parseInt(CustomMQHeader.getString("msgOption1").trim()), CustomMQHeader.getString("msgOption2").trim()); } catch(MQException e) { System.out.println("CustomMQBodyDataBindingSample : MQException from read. Invalid message length.\n" + e); } }
try { this.setDataObject(customerObj); } catch(DataBindingException e) { System.out.println("CustomMQBodyDataBindingSample : DataBindingException from read.\n" + e); } }
/* * This method sets whether or not the data object is to be treated as a business exception. * It is not use here, other then outputting a message to indicate it has been called. * (non-Javadoc) * @see com.ibm.websphere.sca.mq.data.MQBodyDataBinding#setBusinessException(boolean) */ public void setBusinessException(boolean arg0) { System.out.println("CustomMQBodyDataBindingSample - setBusinessException() : arg0 = " + arg0); }
/* * Method not being use for this sample. * This is called after a write, and determines the format string that actually * gets written into the message to identify the body structure. * (non-Javadoc) * @see com.ibm.websphere.sca.mq.data.MQBodyDataBinding#setFormat(java.lang.String) */ public void setFormat(String arg0) { System.out.println("CustomMQBodyDataBindingSample - setFormat() : arg0 = " + arg0); }
/** * Convert the data object into a string and writes it into the output stream. * * The message header indicates the format of the outgoing message, more * specifically the format is dependent upon the msgtype element of the * message header, which can be one of the following: * * DELI * Indicates that the data object should be convert to a delimited string.
* The delimiter is specified in the message header as msgOption1. * FXLN * Indicates that each element of the data object should be converted into a fixed * length string, padded out by a padding character if required.
* The length of each element is specified in the message header as * msgOption1 and the padding character in msgOption2 * * @param arg0 - MQ message descriptor of the outgoing data * @param arg1 - List of MQ header of the outgoing data * @param arg2 - The output stream containing the outgoing data */ public void write(MQMD arg0, List arg1, MQDataOutputStream arg2) throws IOException { System.out.println("CustomMQBodyDataBindingSample - write() : arg0 = " + arg0); System.out.println("CustomMQBodyDataBindingSample - write() : arg1 = " + arg1.toString()); System.out.println("CustomMQBodyDataBindingSample - write() : arg2 = " + arg2); String str = null; DataObject MQHeader = (DataObject) arg1.get(0); DataObject CustomMQHeader = MQHeader.getDataObject("value"); String msgType = CustomMQHeader.getString("msgType"); String msgOption1 = CustomMQHeader.getString("msgOption1"); String msgOption2 = CustomMQHeader.getString("msgOption2");
if(msgType.compareTo("DELI") == 0) { str = writeDelimited(msgOption1.trim()); } if(msgType.compareTo("FXLN") == 0) { str = writeFixedLength(Integer.parseInt(msgOption1), msgOption2); } arg2.writeUTF(str); }
public DataObject getDataObject() throws DataBindingException { System.out.println("CustomMQBodyDataBindingSample - getDataObject() :"); return dataObject; }
public void setDataObject(DataObject arg0) throws DataBindingException { try { System.out.println("CustomMQBodyDataBindingSample - setDataObject() : arg0 = "); printDataObject(arg0); } catch (IOException e) { e.printStackTrace(); } this.dataObject = arg0; }
/** * Convert a delimited data string into a Customer business object. * @param data - A delimited data string containing elements for the Customer business object * @param delimiter - The delimiter used for separating each of the elements of the Customer business object * @return A data object representing the Customer business object. */ private DataObject readDelimited(String data, String delimiter) { System.out.println("CustomMQBodyDataBindingSample - readDelimited() : data = " + data); System.out.println("CustomMQBodyDataBindingSample - readDelimited() : delimiter = " + delimiter); BOFactory boFactory = (BOFactory) new ServiceManager().locateService("com/ibm/websphere/bo/BOFactory"); DataObject addressObj = boFactory.create("http://Library", "Address"); DataObject customerObj = boFactory.create("http://Library", "Customer"); DataObject dObj = customerObj;
String splitted[] = data.split(delimiter); for(int i = 0 ; i < splitted.length ; i++) { if(splitted[i].compareTo("address") == 0) { dObj.setDataObject(names[i], addressObj); dObj = addressObj; } else dObj.setString(names[i], splitted[i]); }
try { System.out.println("CustomMQBodyDataBindingSample - readDelimited() : returns "); printDataObject(customerObj); } catch (IOException e) { e.printStackTrace(); } return customerObj; }
/** * Convert the data object into a delimited string. * @param delimiter - The delimiter for separating each element of * the data object in the string. * @return A string containing all the elements of the data object, * separating by the specified delimiter. */ private String writeDelimited(String delimiter) { System.out.println("CustomMQBodyDataBindingSample - writeDelimited() : delimiter = " + delimiter); String str = new String(); String prefix = ""; try { DataObject dObj = this.getDataObject(); for(int i = 0 ; i < names.length ; i++) { if(names[i].compareTo("address") == 0) { prefix = "address/"; str += "address" + delimiter; } else str += dObj.getString(prefix + names[i]) + delimiter; } } catch(DataBindingException e) { System.out.println("CustomMQBodyDataBindingSample : DataBindingException from write.\n" + e); } System.out.println("CustomMQBodyDataBindingSample - writeDelimited() : returns '" + str + "'"); return str; }
/** * Convert the data string into a Customer business object. * * The data string is in a format that has all the elements of the Customer * business object in a fixed length format. * @param data - The data string containing all the elements in fixed length format * @param len - The length of each element in the string * @param padChar - The padding character for elements shorter than the specified length. * @return A data object representing the Customer business object. * @throws MQException - When the data string is of the wrong length. */ private DataObject readFixedLength(String data, int len, String padChar) throws MQException { System.out.println("CustomMQBodyDataBindingSample - readFixedLength() : data = " + data); System.out.println("CustomMQBodyDataBindingSample - readFixedLength() : len = " + len); System.out.println("CustomMQBodyDataBindingSample - readFixedLength() : padChar = " + padChar); BOFactory boFactory = (BOFactory) new ServiceManager().locateService("com/ibm/websphere/bo/BOFactory"); DataObject addressObj = boFactory.create("http://Library", "Address"); DataObject customerObj = boFactory.create("http://Library", "Customer"); DataObject dObj = customerObj;
// Make sure the message is of the right length if(data.length() % len != 0) throw new MQException(MQException.MQCC_FAILED, MQException.MQRC_DATA_LENGTH_ERROR, data);
int i = 0; do { String element = removePaddingCharacter(data.substring(0, len), padChar); data = data.substring(len); if(element.compareTo("address") == 0) { dObj.setDataObject(names[i], addressObj); dObj = addressObj; } else dObj.setString(names[i], element); i++; } while(data.length() > 0);
try { System.out.println("CustomMQBodyDataBindingSample - readFixedLength() : returns "); printDataObject(customerObj); } catch (IOException e) { e.printStackTrace(); } return customerObj; }
/** * Converts the data object into a fixed length string. * * Converts each of the elements of the data object into a fixed length string and * concatenates all the elements into a string. * @param len - Length of each element of the data object * @param padChar - Padding character for elements shorter than the specified length * @return A string containing all the element of the data object in a fixed length format. */ private String writeFixedLength(int len, String padChar) { System.out.println("CustomMQBodyDataBindingSample - writeFixedLength() : len = " + len); System.out.println("CustomMQBodyDataBindingSample - writeFixedLength() : padChar = " + padChar); String str = new String(); String prefix = ""; try { DataObject dObj = this.getDataObject(); for(int i = 0 ; i < names.length ; i++) { if(names[i].compareTo("address") == 0) { prefix = "address/"; str += addPaddingCharacter(names[i], len, padChar); } else str += addPaddingCharacter(dObj.getString(prefix + names[i]), len, padChar); } } catch(DataBindingException e) { System.out.println("CustomMQDataBindingSample : DataBindingException from write.\n" + e); } System.out.println("CustomMQBodyDataBindingSample - writeFixedLength() : returns '" + str + "'"); return str; }
/** * Remove all the padding characters from the end of the string. * @param str - String with possible padding characters at the end * @param pad - The padding character to be remove * @return A string without the padding characters. */ private String removePaddingCharacter(String str, String pad) { System.out.println("CustomMQBodyDataBindingSample - removePaddingCharacter() : str = " + str); System.out.println("CustomMQBodyDataBindingSample - removePaddingCharacter() : pad = " + pad); // Loop until all the padding characters has been removed. while(str.endsWith(pad)) { str = str.substring(0, str.length() - 1); // Remove the last character. } System.out.println("CustomMQBodyDataBindingSample - removePaddingCharacter() : returns '" + str + "'"); return str; }
/** * Returns a string that is exactly the specified length. * * The returned string will either be truncated, if too long, or have padding character * added to the end, if too short. * @param str - The string to be processed * @param len - The desired length of the return string * @param pad - The padding character to be uses * @return A string of the specified length. */ private String addPaddingCharacter(String str, int len, String pad) { System.out.println("CustomMQBodyDataBindingSample - addPaddingCharacter() : str = " + str); System.out.println("CustomMQBodyDataBindingSample - addPaddingCharacter() : len = " + len); System.out.println("CustomMQBodyDataBindingSample - addPaddingCharacter() : pad = " + pad); // If the string is too long then return a truncated string. if(str.length() >= len) return str.substring(0, len); // Keep adding the padding character until the string is the right length. while(str.length() < len) str += pad; System.out.println("CustomMQBodyDataBindingSample - addPaddingCharacter() : returns '" + str + "'"); return str; }
/** * Print the data object to System.out * @param dataObj The data object to print * @throws IOException */ private void printDataObject(DataObject dataObj) throws IOException { BOXMLSerializer boSer = (BOXMLSerializer)new ServiceManager().locateService("com/ibm/websphere/bo/BOXMLSerializer"); boSer.writeDataObject(dataObj, dataObj.getType().getURI(), dataObj.getType().getName(), System.out); }
}

We could have used 2 custom MQ body data bindings to accomplish the same thing, i.e. one class for processing the delimited message and another for the fixed length message. The reason for implementing both message types in one class is to show how to access the header.

Creating the MQ Function Selector

For the MQ body data binding, create a Java class called CustomMQFunctionSelectorSample in the com.ibm.wesb.sample.MQDataBinding package. It will need to extend the com.ibm.websphere.sca.mq.selector.MQFunctionSelector class.


The content of this class is shown below:

package com.ibm.wesb.sample.MQDataBinding;

import java.io.IOException; import java.util.List;
import com.ibm.mq.data.MQDataInputStream; import com.ibm.websphere.sca.mq.selector.MQFunctionSelector; import com.ibm.websphere.sca.mq.structures.MQMD; import com.ibm.ws.sib.mfp.sdo.OutputHelper;
import commonj.connector.runtime.SelectorException; import commonj.sdo.DataObject;
public class CustomMQFunctionSelectorSample extends MQFunctionSelector { public String generateEISFunctionName(MQMD arg0, String arg1, List arg2, MQDataInputStream arg3) throws IOException, SelectorException { String functionName = "defaultHandler"; for(int i = 0 ; i < arg2.size() ; i++) { DataObject mqHeader = (DataObject)arg2.get(i); if(mqHeader.getString("Format").compareTo("WESBSAMP") == 0) { DataObject customHeader = mqHeader.getDataObject("value"); if(customHeader.getString("msgType").compareTo("DELI") == 0) functionName = "handleMessage"; } } return functionName; } }

The MQ function selector must extend the MQFunctionSelector class, which must override the generateEISFunctionName() method. This method has 4 arguments:

  1. the MQMD for the incoming message
  2. a string for the format name of the incoming message
  3. a list of the MQ headers
  4. the MQ data input stream.

The list of MQ headers will contain the MQ headers that have been processed by the header data binding. The last argument, the MQ data input stream, is an unprocessed stream of the incoming message.

Creating the Mediation Module

To create the mediation module:

  1. Create a new mediation module called CustomMQDataBindingSample.
  2. In the Dependencies section, add the Library project to the Libraries section and the CustomMQDataBindingSamples project to the Java section. Make sure both Deploy with Module check boxes are checked.

  3. In the Assembly Diagram, add an Export and an Import to the flow diagram.
  4. Add the ICustomer interface to all three components of the diagram and add ICustomer as the reference to the mediation module.
  5. Connect the Export to the mediation module and the mediation module to the Import.
  6. Right click on Export and select Generate Binding... -> Messaging Binding... -> MQ Binding to display the WebSphere MQ Export Binding dialog.



  7. We will use JNDI managed resources to connect to MQ so enter the JNDI names of the MQ connection factory and input and output destinations, as shown in the image above.
  8. At the bottom of this dialog, we can enter our custom bindings and function selector classes. Click on the Browse button next to the Request data binding configuration field. In the next dialog, click on the Show data binding classes radio button to show a list of data binding classes, select the com.ibm.wesb.sample.MQDataBinding.CustomMQBodyDataBinding class and press OK.
  9. Back on the WebSphere MQ Export Binding dialog, repeat the previous step for the Response data binding configuration and Function selector configuration fields. Once all fields have been set, press OK.
  10. Back on the Assembly Diagram, right click on Import and select Generate Binding... -> Messaging Binding... -> MQ Binding to display the WebSphere MQ Import Binding dialog.



  11. Repeat steps 7 and 8 to set up the JNDI resources and custom data binding configuration classes, as shown in the image above.

Creating the Mediation Flow

  1. In the Assembly Diagram, double click on the mediation module to open its implementation.
  2. Connect the ICustomer.handleMessage operation on the interface to the ICustomerPartner.handleMessage reference. Select the connection line to display the mediation flow in the mediation flow editor.
  3. From the palette select the Custom Mediation primitive onto the canvas and connect it to the Input and the Callout (the exception terminal may be connected to a Fail primitive if desired). We will be using the custom mediation to alter the message type for the output.



  4. Go to the Details tab in the custom mediation's Properties panel and enter the following Java code:
    // Change the custom MQ header to Fixed Length output.
     List mqHeaders = smo.getHeaders().getMQHeader().getHeader(); // Get list of MQ headers
     // Look for the WESBSAMP header in the list of MQ headers
     for(int i = 0 ; i < mqHeaders.size() ; i++)
     {
     	DataObject header = (DataObject)mqHeaders.get(i);
     	if(header.getString("Format").compareTo("WESBSAMP") == 0)
     	{
     		DataObject customHeader = header.getDataObject("value");
     		customHeader.setString("msgType", "FXLN");  // Change the message type to Fixed Length output
     		customHeader.setString("msgOption1", "15"); // Specify the length of each element
     		customHeader.setString("msgOption2", "~");  // Specify the padding character to use
     	}
     }

    The Java code sets the message type to fixed length (FXLN), with each element 15 characters long and the '~' as the padding character.
  5. In the Java Imports tab add the following two lines:
    import java.util.List;
    import commonj.sdo.DataObject;
  6. For the response message, repeat steps 3 to 5 above but replace the Java code with the following:
    List mqHeaders = smo.getHeaders().getMQHeader().getHeader();
     for(int i = 0 ; i < mqHeaders.size() ; i++)
     {
       DataObject header = (DataObject)mqHeaders.get(i);
       if(header.getString("Format").compareTo("WESBSAMP") == 0)
       {
         DataObject customHeader = header.getDataObject("value");
         customHeader.setString("msgType", "DELI");
         customHeader.setString("msgOption1", ",   ");
         customHeader.setString("msgOption2", "    ");
       }
     }

This completes the creation of the sample.