Hangin' with the JAX Pack, Part 2: JAXM
Pages: 1, 2, 3, 4
Message Consumers and JAXMServlet
|
Related Reading
|
The first, and perhaps simplest, method for taking advantage of JAXM functionality
is by developing a servlet that extends the JAXMServlet
interface and consumes XML messages packaged via SOAP 1.1. JAXMServlets
look surprisingly like message-driven Enterprise Java Beans, in that they have a single onMessage(Message
msg) method that needs to be implemented. The reality, however, is that they
are traditional servlets and that the onMessage
method gets called whenever a servlet POST or GET action occurs. When onMessage()
is called we can then decompose the underlying SOAP message, as required by the
application. Let's look at a complete example, adapted from public draft 1, that
takes a SOAP trade message and dumps it to System.out.
Listing 1: SOAPListener.java
00 /*
01 * adapted from a sun example
02 */
03 import javax.xml.messaging.*;
04 import javax.xml.soap.*;
05 import javax.xml.parsers.*;
06 import javax.xml.transform.*;
07 import javax.activation.DataHandler;
08 import java.io.*;
09 import org.w3c.dom.*;
10 import org.xml.sax.SAXException;
11 public class SOAPListener extends JAXMServlet implements AsyncListener {
12 // implement the required onMessage method
13 public void onMessage(Message message) {
14 try {
15 //Get the soap part of the message (ignore attachments)
16 SOAPPart soapPart = message.getSOAPPart( );
17
18 // tunnel in and get the envelope
19
20 SOAPEnvelope soapEnvelope = soapPart.getSOAPEnvelope( );
21
22 // from the envelope get the DOM tree representing the content.
23 DOMSource domSrc = (DOMSource) soapEnvelope.getContentAs(DOMSource.FEATURE );
24
25 //Now use the dom tree to traverse the info.
26 //get some of the fields from it.
27 Document doc = (Document) domSrc.getNode();
28 Element root = doc.getDocumentElement();
29 NodeList list = root.getElementsByTagName("GetLastTradePriceDetailed" );
30 Element element;
31 Element childElement;
32 for(int i = ; i < list.getLength(); i++){
33 if (!(list.item(i) instanceof Element )) continue;
34 element = (Element list.item(i) );
35 NodeList list2 = element.getChildNodes();
36 for(int j = ; j < list2.getLength( ; j++ {
37 if(!(list2.item(j instanceof Element) continue;
38 childElement = (Element list2.item(j ;
39 System.out.println(childElement.getTagName() ;
40 System.out.println("\t" ;
41 System.out.println( ((Text) childElement.getFirstChild()).getData()) ;
42 System.out.println("\n" );
43 }
44 }
45 } // end try
46 catch(Exception jxe ) {
47 jxe.printStackTrace();
48 }
49 } // end onMessage
50 } // end SOAPListener
Breaking the example down, we see that lines 3-10 simply import the required
packages to support JAXM (see the JAXM specification for details). On line
11 we've defined an AsyncListener
listener. Note that SynchListeners
are expected to return a SOAPmessage
object. Servlets must implement either the AsyncListener
or SyncListener, depending on
what behavior you want. Line 13 shows the first real line of code, the definition
of the onMessage() method with
its single message argument, defined in the javax.xml.messaging
package. It's interesting to note that the specification provides classes and methods
that closely parallel the SOAP 1.1 specification. Specifically, messages contain
a SOAP part, which contains a SOAP Envelope, containing a SOAP Header and Body,
etc.
Lines 16 and 20, respectively, show how we obtain the object representing the
SOAP envelope, as shown in figure 3. The various SOAP message class information
is detailed in the javax.xml.soap
package. Note that we could have just as easily obtained the attachment part
of the message by writing:
AttachmentPart attachmentPart = message.getAttachmentPart( );
|
A word of caution: the EA2 version of the JAXM contains documentation for the JAXM packages that is unfortunately sketchy. I have tried to be as accurate as possible, but some of the information on JAXM was obtained by decompiling and examining source! |
Once we have the SOAPEnvelope
we can obtain the data representing the encapsulated XML using the getContentAs()
method. GetContentAs returns any of a number of
javax.xml.transform.Source types, of which we chose DOMSource.FEATURE,
but could have chosen SAXSource.FEATURE
or STREAMSource.FEATURE, depending
on how we wanted to process the result.
Since we choose to process the content as a DOM Tree, we use the DOMSource
object to get the DOM Document
representing the XML content; then we can then use the various DOM APIs to process
the data.
The steps we went through to develop our JAXM Servlet were:
- Import the required packages.
- Implement either
AsynchListenerorSyncListener. - Implement the
onMessagemethod (other parts may be available in the future). - Obtain the SOAP part of the message.
- Obtain the SOAP Envelope or attachment.
- Tunnel down into the appropriate Envelope or attachment field as required.
- Optionally, for
SyncListeners, return an appropriateSOAPMessage.
Before we close our discussion of JAXM, let's spend a few moments looking at message producers as well.
