Work with the message payload
We can work with the message payload in a pre-existing mediation handler, and transcode the message payload from one message format to another.
Create or open a mediation handler in an EJB project. For more information, see Writing a mediation handler. You should also read the tips for successfully programming mediations in the topic Coding tips for mediations programming.
We can use this task to complete some or all of the following actions on the message payload:
- Locate the data objects within the message payload
- Convert the payload into another format
- Convert the payload into a byte array, for example if we want our mediation to log messages.
To work with the contents of a message, use the SIMessage and SIMessageContext APIs. Additionally, use SIMediationSession to provide your mediation with access to the service integration bus, to send and receive messages. For more information, see:
To work with specific fields within a message, use Service Data Objects (SDO) Version 1 data graphs. For more information, see SDO data graphs. For more information about the format of supported message types, and examples of how to work with them, see Mapping of SDO data graphs for web services messages.
To work with the message payload, take the following steps:
- Locate the point in the mediation handler where you insert the functional mediation code, in the method handle (MessageContext context). The interface is MessageContext, and you should cast this to SIMessageContext unless you only want to work with the methods provided by MessageContext.
- Retrieve the data graph of the message payload as follows:
- Get the SIMessage from the MessageContext object. For example:
SIMessage message = ((SIMessageContext)context).getSIMessage();
- Get the message format string to determine its type. For example:
String messageFormat = message.getFormat();
- Retrieve the DataGraph object from the message. For example:
DataGraph dataGraph = message.getDataGraph();
For more information, see SDO data graphs.
- Optional: Locate data objects within the payload:
- Navigate within the graph to a named DataObject. For example, where DataObject has the name "data":
DataObject dataObject = dataGraph.getRootObject().getDataObject("data");
- Retrieve information contained in the data object. For example, if the message is a text message:
String textInfo = dataObject.getString("value");
- Work with the fields within the message. For an example of how to do this, see Example code for message fields.
- Optional: Transcode the payload into another format:
- Review the topic Transcoding between message formats to understand the implications of transcoding the payload.
- Call the method getNewDataGraph, passing the new format as a parameter, which returns a copy of the payload in the new format. For example:
DataGraph newDataGraph = message.getNewDataGraph(newFormat);
- Write the data graph in the new format back to the message using the setDataGraph method. For example:
message.setDataGraph(newDataGraph, newFormat);
- Optional: Convert the payload into a stream of bytes:
- Review the topics Transcoding a message payload into a byte array and Transcoding a byte array into a message payload to understand the implications of converting between message format and byte stream, and back again.
- Call the method getDataGraphAsBytes, which returns a copy of the payload as a byte stream. For example:
byte[] newByteArray = message.getDataGraphAsBytes();
- Call the method createDataGraph provided by the SIDataGraphFactory API, which creates a new data graph by parsing the bytes according to the format passed to the method. For example:
DataGraph newDataGraph = SIDataGraphFactory.getInstance().createDataGraph( byteArray, format);
- Work with the message as a stream of bytes. For an example of how to do this, see Example code for message fields
- Return True in the mediation code so that the MessageContext is passed to the next mediation handler in the handler list. If the return value is False the MessageContext will be discarded and will not be delivered to the destination.
If the mediation handler is the last handler in the handler list, and the forward routing path is empty, the message is made available to consuming applications on that destination. If the forward routing path not empty, the message is not made available to any consumers on that destination. Instead, the message is forwarded to the next destination in the routing path.
Example code for message fields
Below is an example of the code for a mediation for working with a field in a message:public boolean handle(MessageContext context) throws MessageContextException { /* Get the SIMessage from the MessageContext object */ SIMessage message = ((SIMessageContext)context).getSIMessage(); /* Get the message format string */ String messageFormat = message.getFormat(); /* If we have a JMS TextMessage then extract the text contained in the message. */ if(messageFormat.equals("JMS:text")) { /* Retrieve the DataGraph object from the message */ DataGraph dataGraph = message.getDataGraph(); /* Navigate down the DataGraph to the DataObject named 'data'. */ DataObject dataObject = dataGraph.getRootObject().getDataObject("data"); /* Retrieve the text information contained in the DataObject. */ String textInfo = dataObject.get("value"); /* Use the text information retrieved */ System.out.println(textInfo); } /* Return true so the MessageContext is passed to any other mediation handlers * in the handler list */ return true; }The complete mediation function code for working with the message payload as a stream of bytes might look like this example:public boolean handle(MessageContext context)throws MessageContextException { /* Get the SIMessage from the MessageContext object */ SIMessage message = ((SIMessageContext)context).getSIMessage(); if (!SIApiConstants.JMS_FORMAT_MAP.equals(msg.getFormat())) { try { dumpBytes(msg.getDataGraphAsBytes()); } catch(Exception e) { System.out.println("The message contents could not be retrieved due to a "+e); } } else { System.out.println("The bytes for a JMS:map format message cannot be shown."); } return true; } private static void dumpBytes(byte[] bytes) { // Subroutine to dump the bytes in a readable form to System.out } }
Subtopics
- MediationHandler
The public interface MediationHandler has just one method: handle. This method is used by the runtime to invoke a mediation.
- SIMessageContext
Public interface SIMessageContext extends javax.xml.rpc.handler.MessageContext. This is the object required on the interface of a mediation handler. In addition to the context information that might be passed from one handler to another, it can return a reference to an SIMessage and an SIMediationSession.
- Transcoding between message formats
A mediation can convert a message from one format to another without changing the semantic meaning of the message. This operation is referred to as transcoding a message.