This section explains how you can send, receive, and process a JMS message that contains a SOAP payload.
Message Queue provides a utility to help you send and receive SOAP messages using the JMS API. With the support it provides, you can convert a SOAP message into a JMS message and take advantage of the reliable messaging service offered by Message Queue. You can then convert the message back into a SOAP message on the receiving side and use SAAJ to process it.
To send, receive, and process a JMS message that contains a SOAP payload, you must do the following:
Import the library com.sun.messaging.xml.MessageTransformer . This is the utility whose methods you will use to convert SOAP messages to JMS messages and vice versa.
Before you transport a SOAP message, you must call the MessageTransformer.SOAPMessageIntoJMSMessage method. This method transforms the SOAP message into a JMS message. You then send the resulting JMS message as you would a normal JMS message. For programming simplicity, it would be best to select a destination that is dedicated to receiving SOAP messages. That is, you should create a particular queue or topic as a destination for your SOAP message and then send only SOAP messages to this destination.
Message myMsg= MessageTransformer.SOAPMessageIntoJMSMessage (SOAPMessage, Session);
The Session argument specifies the session to be used in producing the Message.
On the receiving side, you get the JMS message containing the SOAP payload as you would a normal JMS message. You then call the MessageTransformer.SOAPMessageFromJMSMessage utility to extract the SOAP message, and then use SAAJ to disassemble the SOAP message and do any further processing. For example, to obtain the SOAPMessage make a call like the following:
SOAPMessage myMsg= MessageTransformer.SOAPMessageFromJMSMessage (Message, MessageFactory);
The MessageFactory argument specifies a message factory that the utility should use to construct the SOAPMessage from the given JMS Message.
The following sections offer several use cases and code examples to illustrate this process.
In the first example, illustrated in Figure 5–9, an incoming SOAP message is received by a servlet. After receiving the SOAP message, the servlet MyServlet uses the MessageTransformer utility to transform the message into a JMS message, and (reliably) forwards it to an application that receives it, turns it back into a SOAP message, and processes the contents of the SOAP message.
For information on how the servlet receives the SOAP message, see Writing a SOAP Service.
Instantiate a ConnectionFactory object and set its attribute values, for example:
QueueConnectionFactory myQConnFact = new com.sun.messaging.QueueConnectionFactory(); |
Use the ConnectionFactory object to create a Connection object.
QueueConnection myQConn = myQConnFact.createQueueConnection(); |
Use the Connection object to create a Session object.
QueueSession myQSess = myQConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); |
Instantiate a Message Queue Destination administered object corresponding to a physical destination in the Message Queue message service. In this example, the administered object is mySOAPQueue and the physical destination to which it refers is myPSOAPQ.
Queue mySOAPQueue = new com.sun.messaging.Queue("myPSOAPQ"); |
Use the MessageTransformer utility, as shown, to transform the SOAP message into a JMS message. For example, given a SOAP message named MySOAPMsg,
Message MyJMS = MessageTransformer.SOAPMessageIntoJMSMessage (MySOAPMsg, MyQSess); |
Create a QueueSender message producer.
This message producer, associated with mySOAPQueue, is used to send messages to the queue destination named myPSOAPQ.
QueueSender myQueueSender = myQSess.createSender(mySOAPQueue); |
Send a message to the queue.
myQueueSender.send(myJMS); |
Instantiate a ConnectionFactory object and set its attribute values.
QueueConnectioFactory myQConnFact = new com.sun.messaging.QueueConnectionFactory(); |
Use the ConnectionFactory object to create a Connection object.
QueueConnection myQConn = myQConnFact.createQueueConnection(); |
Use the Connection object to create one or more Session objects.
QueueSession myRQSess = myQConn.createQueueSession(false, session.AUTO_ACKNOWLEDGE); |
Instantiate a Destination object and set its name attribute.
Queue myRQueue = new com.sun.messaging.Queue("mySOAPQ"); |
Use a Session object and a Destination object to create any needed MessageConsumer objects.
QueueReceiver myQueueReceiver = myRQSess.createReceiver(myRQueue); |
If needed, instantiate a MessageListener object and register it with a MessageConsumer object.
Start the QueueConnection you created in Example 1: Deferring SOAP Processing. Messages for consumption by a client can only be delivered over a connection that has been started.
myQConn.start(); |
Receive a message from the queue.
The code below is an example of a synchronous consumption of messages:
Message myJMS = myQueueReceiver.receive(); |
Use the Message Transformer to convert the JMS message back to a SOAP message.
SOAPMessage MySoap = MessageTransformer.SOAPMessageFromJMSMessage (myJMS, MyMsgFactory); |
If you specify null for the MessageFactory argument, the default Message Factory is used to construct the SOAP Message.
Disassemble the SOAP message in preparation for further processing. See The SOAP Message Object for information.
In the next example, illustrated in Figure 5–10, an incoming SOAP message is received by a servlet. The servlet packages the SOAP message as a JMS message and (reliably) forwards it to a topic. Each application that subscribes to this topic, receives the JMS message, turns it back into a SOAP message, and processes its contents.
The code that accomplishes this is exactly the same as in the previous example, except that instead of sending the JMS message to a queue, you send it to a topic. For an example of publishing a SOAP message using Message Queue, see Example 5–5.
This section includes and describes two code samples: one that sends a JMS message with a SOAP payload, and another that receives the JMS/SOAP message and processes the SOAP message.
Example 5–5 illustrates the use of the JMS API, the SAAJ API, and the JAF API to send a SOAP message with attachments as the payload to a JMS message. The code shown for the SendSOAPMessageWithJMS includes the following methods:
A constructor that calls the init method to initialize all the JMS objects required to publish a message
A send method that creates the SOAP message and an attachment, converts the SOAP message into a JMS message, and publishes the JMS message
A close method that closes the connection
A main method that calls the send and close methods
//Libraries needed to build SOAP message import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPPart; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPElement; import javax.xml.soap.MessageFactory; import javax.xml.soap.AttachmentPart; import javax.xml.soap.Name //Libraries needed to work with attachments (Java Activation Framework API) import java.net.URL; import javax.activation.DataHandler; //Libraries needed to convert the SOAP message to a JMS message and to send it import com.sun.messaging.xml.MessageTransformer; import com.sun.messaging.BasicConnectionFactory; //Libraries needed to set up a JMS connection and to send a message import javax.jms.TopicConnectionFactory; import javax.jms.TopicConnection; import javax.jms.JMSException; import javax.jms.Session; import javax.jms.Message; import javax.jms.TopicSession; import javax.jms.Topic; import javax.jms.TopicPublisher; //Define class that sends JMS message with SOAP payload public class SendSOAPMessageWithJMS{ TopicConnectionFactory tcf = null; TopicConnection tc = null; TopicSession session = null; Topic topic = null; TopicPublisher publisher = null; //default constructor method public SendSOAPMessageWithJMS(String topicName){ init(topicName); } //Method to nitialize JMS Connection, Session, Topic, and Publisher public void init(String topicName) { try { tcf = new com.sun.messaging.TopicConnectionFactory(); tc = tcf.createTopicConnection(); session = tc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); topic = session.createTopic(topicName); publisher = session.createPublisher(topic); } //Method to create and send the SOAP/JMS message public void send() throws Exception{ MessageFactory mf = MessageFactory.newInstance(); //create default factory SOAPMessage soapMessage=mfcreateMessage(); //create SOAP message object SOAPPart soapPart = soapMessage.getSOAPPart();//start to drill down to body SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); //first the envelope SOAPBody soapBody = soapEnvelope.getBody(); Name myName = soapEnvelope.createName("HelloWorld", "hw", http://www.sun.com/imq’); //name for body element SOAPElement element = soapBody.addChildElement(myName); //add body element element.addTextNode("Welcome to SUnOne Web Services."); //add text value //Create an attachment with the Java Framework Activation API URL url = new URL("http://java.sun.com/webservices/"); DataHandler dh = new DataHnadler (url); AttachmentPart ap = soapMessage.createAttachmentPart(dh); //Set content type and ID ap.setContentType("text/html"); ap.setContentID(’cid-001"); //Add attachment to the SOAP message soapMessage.addAttachmentPart(ap); soapMessage.saveChanges(); //Convert SOAP to JMS message. Message m = MessageTransformer.SOAPMessageIntoJMSMessage (soapMessage,session); //Publish JMS message publisher.publish(m); //Close JMS connection public void close() throws JMSException { tc.close(); } //Main program to send SOAP message with JMS public static void main (String[] args) { try { String topicName = System.getProperty("TopicName"); if(topicName == null) { topicName = "test"; } SendSOAPMEssageWithJMS ssm = new SendSOAPMEssageWithJMS(topicName); ssm.send(); ssm.close(); } catch (Exception e) { e.printStackTrace(); } } }
Example 5–6 illustrates the use of the JMS API, SAAJ, and the DOM API to receive a SOAP message with attachments as the payload to a JMS message. The code shown for the ReceiveSOAPMessageWithJMS includes the following methods:
A constructor that calls the init method to initialize all the JMS objects needed to receive a message.
An onMessage method that delivers the message and which is called by the listener. The onMessage method also calls the message transformer utility to convert the JMS message into a SOAP message and then uses SAAJ to process the SOAP body and uses SAAJ and the DOM API to process the message attachments.
A main method that initializes the ReceiveSOAPMessageWithJMS class.
//Libraries that support SOAP processing import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPMessage; import javax.xml.soap.AttachmentPart //Library containing the JMS to SOAP transformer import com.sun.messaging.xml.MessageTransformer; //Libraries for JMS messaging support import com.sun.messaging.TopicConnectionFactory //Interfaces for JMS messaging import javax.jms.MessageListener; import javax.jms.TopicConnection; import javax.jms.TopicSession; import javax.jms.Message; import javax.jms.Session; import javax.jms.Topic; import javax.jms.JMSException; import javax.jms.TopicSubscriber //Library to support parsing attachment part (from DOM API) import java.util.iterator; public class ReceiveSOAPMessageWithJMS implements MessageListener{ TopicConnectionFactory tcf = null; TopicConnection tc = null; TopicSession session = null; Topic topic = null; TopicSubscriber subscriber = null; MessageFactory messageFactory = null; //Default constructor public ReceiveSOAPMessageWithJMS(String topicName) { init(topicName); } //Set up JMS connection and related objects public void init(String topicName){ try { //Construct default SOAP message factory messageFactory = MessageFactory.newInstance(); //JMS set up tcf = new. com.sun.messaging.TopicConnectionFactory(); tc = tcf.createTopicConnection(); session = tc.createTopicSesstion(false, Session.AUTO_ACKNOWLEDGE); topic = session.createTopic(topicName); subscriber = session.createSubscriber(topic); subscriber.setMessageListener(this); tc.start(); System.out.println("ready to receive SOAP m essages..."); }catch (Exception jmse){ jmse.printStackTrace(); } } //JMS messages are delivered to the onMessage method public void onMessage(Message message){ try { //Convert JMS to SOAP message SOAPMessage soapMessage = MessageTransformer.SOAPMessageFromJMSMessage (message, messageFactory); //Print attchment counts System.out.println("message received! Attachment counts: " + soapMessage.countAttachments()); //Get attachment parts of the SOAP message Iterator iterator = soapMessage.getAttachments(); while (iterator.hasNext()) { //Get next attachment AttachmentPart ap = (AttachmentPart) iterator.next(); //Get content type String contentType = ap.getContentType(); System.out.println("content type: " + conent TYpe); //Get content id String contentID = ap.getContentID(); System.out.println("content Id:" + contentId); //Check to see if this is text if(contentType.indexOf"text")>=0 { //Get and print string content if it is a text attachment String content = (String) ap.getContent(); System.outprintln("*** attachment content: " + content); } } }catch (Exception e) { e.printStackTrace(); } } //Main method to start sample receiver public static void main (String[] args){ try { String topicName = System.getProperty("TopicName"); if( topicName == null) { topicName = "test"; } ReceiveSOAPMessageWithJMS rsm = new ReceiveSOAPMessageWithJMS(topicName); }catch (Exception e) { e.printStackTrace(); } } }