The JavaTM Web Services Tutorial
Home
TOC
PREV TOP NEXT

Code Examples

The first part of this tutorial used code fragments to walk you through the basics of using the JAXM API. This section puts some of the code fragments you created into the program Request.java and also creates the application MyUddiPing.java, which you can run.


Note: <JWSDP_HOME> is the directory where you unpacked the Java Web Services Developer Pack. The code examples use the Unix form $JWSDP_HOME; for Windows, substitute the equivalent form %JWSDP_HOME%.

Request.java

The class Request.java is shown here and is also included in the <JWSDP_HOME>/docs/tutorial/examples/jaxm directory. It is based on the message you built as an example of a standalone client sending a request-response message. In addition to putting all the code together, it adds import statements, a main method, and a try/catch block with exception handling.

import javax.xml.soap.*;	
import javax.xml.messaging.*;	
import java.io.*;	
import java.util.*;
 
public class Request {	
   public static void main(String[] args)   {	
      try {	
         SOAPConnectionFactory scFactory =	
               SOAPConnectionFactory.newInstance();	
         SOAPConnection con = scFactory.createConnection();
 
         MessageFactory factory =	
               MessageFactory.newInstance();	
         SOAPMessage message = factory.createMessage();
 
         SOAPPart soapPart = message.getSOAPPart();	
         SOAPEnvelope envelope = soapPart.getEnvelope();	
         SOAPHeader header = envelope.getHeader();	
         SOAPBody body = envelope.getBody();	
         header.detachNode();
 
         Name bodyName = envelope.createName(	
                     "GetLastTradePrice", "m",	
                     "http://wombats.ztrade.com");	
         SOAPBodyElement gltp =	
               body.addBodyElement(bodyName);
 
         Name name = envelope.createName("symbol");	
         SOAPElement symbol = gltp.addChildElement(name);	
         symbol.addTextNode("SUNW");
 
         URLEndpoint endpoint = new URLEndpoint(	
               "http://wombat.ztrade.com/quotes");	
         SOAPMessage response = con.call(message,	
                              endpoint);
 
         con.close();
 
         SOAPPart sp = response.getSOAPPart();	
         SOAPEnvelope se = sp.getEnvelope();	
         SOAPBody sb = se.getBody();
 
         Iterator it = sb.getChildElements(bodyName);	
         SOAPBodyElement bodyElement =	
                     (SOAPBodyElement)it.next();	
         String lastPrice = bodyElement.getValue();
 
         System.out.print("The last price for SUNW is ");	
         System.out.println(lastPrice);
 
      } catch (Exception ex) {	
         ex.printStackTrace();	
      }	
   }	
}
 

In order for Request.java to be runnable, the URLEndpoint object in it has to be a valid existing site, which is not true in this case. However, the application in the next section is one that you can run.

MyUddiPing.java

The sample program UddiPing.java is another example of a standalone application. A Universal Description, Discovery and Integration (UDDI) service is a business registry and repository from which you can get information about businesses that have registered themselves with the registry. In this case, the UddiPing application is not actually accessing a UDDI service registry but rather a test (demo) version. Because of this, the number of businesses you can get information about is limited. Nevertheless, UddiPing demonstrates a request being sent and a response being received. The application prints out the complete message that is returned, that is, the complete XML document as it looks when it comes over the wire. Later in this section you will see how to rewrite UddiPing.java so that in addition to printing out the entire XML document, it also prints out just the text content of the response. This makes it much easier to see the information you want.

In order to get a better idea of how to run the UddiPing example, take a look at the directory <JWSDP_HOME>/samples/jaxm/uddiping. This directory contains the subdirectory src and the files run.sh, uddi.properties, UddiPing.class, and README. The README file tells you what you need to do to run the application, which is explained more fully here.

The README file directs you to modify the file build.properties, which contains the URL of the destination (the UDDI test registry) and the proxy host and proxy port of the sender. You will need to modify this file so that it has your proxy host and your proxy port. If you are in the uddiping directory when you call the run.sh script, the information in the run script should be correct already.

The run.sh script calls the java command on UddiPing. First it sets the location of the java command and then prints a usage message if two arguments are not supplied. Perhaps the main thing it does is to set your classpath so that the necessary .jar files can be found.

Here is what you type at the command line if you want to get information about, for example, Oracle:

run.sh uddi.properties Oracle
 

Executing the run script as shown in the preceding command line should produce an XML document with the name and description of Oracle as the content. However, these are embedded in the XML document, which makes them difficult to see. The next section adds code to UddiPing.java that extracts the content so that it is readily visible.

Creating MyUddiPing.java

To make the response to UddiPing.java easier to read, you will create a new file called MyUddiPing.java, which extracts the content and prints it out. You will see how to write the new file later in this section after setting up a new directory with the necessary files. Because the name of the new file is MyUddiPing.java, you need to create the directory myuddiping under the <JWSDP_HOME>/samples/jaxm directory. Then copy all of the files from the uddiping directory into the myuddiping directory.

cd $JWSDP_HOME/samples/jaxm	
mkdir myuddiping	
cp uddiping/* myuddiping
 

Open run.sh and change UddiPing to MyUddiPing so that the run script will be called on the correct file.

The MyUddiPing.class file will be added to the directory myuddiping as part of the execution of the run.sh script. The run.sh script will be examined more later.

The src directory will not have been copied from uddiping because it is not a file, so you need to create your own src directory. Then go to the src directory and create the file MyUddiPing.java using your favorite editor.

cd myuddiping	
mkdir src
 

For convenience, you can copy MyUddiPing.java from the examples directory to your new src directory as follows:

UNIX:

cd $JWSDP_HOME/docs/tutorial/examples/jaxm	
cp MyUddiPing.java $JWSDP_HOME/samples/jaxm/myuddiping/src
 

Windows:

cd %JWSDP_HOME%\docs\tutorial\examples\jaxm	
cp MyUddiPing.java %JWSDP_HOME%\samplels\jaxm\myuddiping\src
 

Now let's go through the file a few lines at a time. Note that most of the class MyUddiPing.java is based on UddiPing.java. You will be adding a section at the end that accesses only the content you want from the response that is returned by the method call.

The first four lines of code import the packages used in the application.

import javax.xml.soap.*;	
import javax.xml.messaging.*;	
import java.util.*;	
import java.io.*;
 

The next few lines begin the definition of the class MyUddiPing, which starts with the definition of its main method. The first thing it does is check to see if two arguments were supplied. If not, it prints a usage message and exits. (Note that if one of the run scripts is used, the check will already have been done, so there will always be two arguments to get to this point.)

public class MyUddiPing {	
   public static void main(String[] args) {	
      try {	
         if (args.length != 2) {	
            System.err.println("Usage: UddiPing " +	
               "properties-file business-name");	
            System.exit(1);	
         }
 

The following lines create a java.util.Properties file that contains the system properties and the properties from the file uddi.properties that is in the myuddiping directory.

         Properties myprops = new Properties();	
         myprops.load(new FileInputStream(args[0]));	
         Properties props = System.getProperties();	
         Enumeration it = myprops.propertyNames();	
         while (it.hasMoreElements()) {	
            String s = (String) it.nextElement(); 	
            props.put(s, myprops.getProperty(s));	
         } 
 

The next four lines create a SOAPMessage object. First, the code gets an instance of SOAPConnectionFactory and uses it to create a connection. Then it gets an instance of MessageFactory and uses it to create a message.

         SOAPConnectionFactory scf =	
               SOAPConnectionFactory.newInstance();	
         SOAPConnection connection =	
               scf.createConnection();	
         MessageFactory msgFactory =	
               MessageFactory.newInstance();	
         SOAPMessage msg = msgFactory.createMessage(); 
 

The new SOAPMessage object msg automatically contains a SOAPPart object that contains a SOAPEnvelope object. The SOAPEnvelope object contains a SOAPBody object, which is the element you want to access in order to add content to it. The next lines of code get the SOAPPart object, the SOAPEnvelope object, and the SOAPBody object.

         SOAPEnvelope envelope =	
                  msg.getSOAPPart().getEnvelope();	
         SOAPBody body = envelope.getBody();
 

The following lines of code add an element with a fully-qualified name and then add two attributes to the new element. The first attribute has the name "generic" and the value "1.0". The second attribute has the name "maxRows" and the value "100". Then the code adds a child element with the name name and adds some text to it with the method addTextNode. The text added is the String object that was passed in as the second argument, which is the name of the business that is being searched for in the test registry.

         SOAPBodyElement findBusiness =	
               body.addBodyElement(	
               envelope.createName("find_business",	
               "", "urn:uddi-org:api"));	
         findBusiness.addAttribute(	
               envelope.createName("generic", "1.0");	
         findBusiness.addAttribute(	
               envelope.createName("maxRows", "100");	
         SOAPElement businessName =	
               findBusiness.addChildElement(	
               envelope.createName("name"));	
         businessName.addTextNode(args[1]); 
 

The next line of code creates the URLEndpoint object that is the destination for this message. It gets the value of the property named "URL" from the system property file.

         URLEndpoint endpoint = new URLEndpoint(	
            System.getProperties().getProperty("URL"));
 

The following line of code saves the changes that have been made to the message. This method will be called automatically when the message is sent, but it does not hurt to call it explicitly.

          msg.saveChanges(); 
 

Next the message msg is sent to the destination that endpoint represents, which is the test UDDI registry. The method call will block until it gets a SOAPMessage object back, at which point it returns the reply.

         SOAPMessage reply = connection.call(msg,	
                                 endpoint);
 

In the next two lines, the first prints out a line giving the URL of the sender (the test registry), and the second prints out the returned message as an XML document.

         System.out.println("Received reply from: " +	
                                 endpoint);	
         reply.writeTo(System.out);
 

The code thus far has been based on UddiPing.java. If you go to the uddiping directory and call the appropriate run script, you can see what the output looks like.

UNIX:

cd $JWSDP_HOME/samples/jaxm/uddiping	
run.sh uddi.properties Microsoft
 

Windows:

cd %JWSDP_HOME%\samples\jaxm\uddiping	
run.bat uddi.properties Microsoft
 

What appears on your screen will look something like this:

Received replyfrom: 
http://www3.ibm.com/services/uddi/testregistry/inquiryapi<?xml 
version="1.0" encoding="UTF-8" ?><Envelope 
xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body><busin
essList generic="1.0" xmlns="urn:uddi-org:api" 
operator="www.ibm.com/services/uddi" 
truncated="false"><businessInfos><businessInfo 
businessKey="D7475060-BF58-11D5-A432-
0004AC49CC1E"><name>Microsoft Corporation</name><description 
xml:lang="en">Computer Software and Hardware 
Manufacturer</description><serviceInfos></serviceInfos></busin
essInfo></businessInfos></businessList></Body></Envelope>
 

Adding New Code

Now you are going to add code to make the reply more user-friendly. Your new code will get the content from certain elements rather than printing out the whole XML document as it was sent over the wire. Because the content is in the SOAPBody object, the first thing you need to do is access it, as shown in the following line of code. You can access each element in separate method calls, as was done in earlier examples, or you can access the SOAPBody object using this shorthand version.

SOAPBody replyBody =	
      reply.getSOAPPart().getEnvelope().getBody();
 

Next you might print out two blank lines to separate your results from the raw XML message and a third line that describes the text that follows.

         System.out.println("");	
         System.out.println("");	
         System.out.print(	
          "Content extracted from the reply message: ");
 

Now you can begin the process of getting all of the child elements from an element, getting the child elements from each of those, and so on, until you arrive at a text element that you can print out. Unfortunately, the registry used for this example code, being just a test registry, is not always consistent. The number of subelements sometimes varies, making it difficult to know how many levels down the code needs to go. And in some cases, there are multiple entries for the same company name.

The code you will be adding drills down through the subelements within the SOAP body and retrieves the name and description of the company in most cases. The method you use to retrieve child elements is the SOAPElement method getChildElements. When you give this method no arguments, it retrieves all of the child elements of the element on which it is called. If you know the Name object used to name an element, you can supply that to getChildElements and retrieve only the children with that name. In this case, however, you need to retrieve all elements and keep drilling down until you get to the elements that contain text content.

Here is the basic pattern that is repeated for drilling down:

         Iterator iter1 = replyBody.getChildElements();	
         while (iter1.hasNext()) { 	
            SOAPBodyElement bodyElement =	
                  (SOAPBodyElement)iter1.next();	
            Iterator iter2 =	
                  bodyElement.getChildElements();	
            while (iter2.hasNext()) {
 

The method getChildElements returns the elements in the form of a java.util.Iterator object. You access the child elements by calling the method next on the Iterator object. The method Iterator.hasNext can be used in a while loop because it returns true as long as the next call to the method next will return a child element. The loop ends when there are no more child elements to retrieve.

An immediate child of a SOAPBody object is a SOAPBodyElement object, which is why calling iter1.next returns a SOAPBodyElement object. Children of SOAPBodyElement objects and all child elements from there down are SOAPElement objects. For example, the call iter2.next returns the SOAPElement object child2. Note that the method Iterator.next returns an Object, which has to be narrowed (cast) to the specific kind of object you are retrieving. Thus, the result of calling iter1.next is cast to a SOAPBodyElement object, whereas the results of calling iter2.next, iter3.next, and so on, are all cast to a SOAPElement object.

Here is the code you add to access and print out the company name and description:

         Iterator iter1 = replyBody.getChildElements();	
         while (iter1.hasNext()) { 	
            SOAPBodyElement bodyElement =	
                  (SOAPBodyElement)iter1.next();	
            Iterator iter2 =	
                  bodyElement.getChildElements();	
            while (iter2.hasNext()) {	
               SOAPElement child2 =	
                  (SOAPElement)iter2.next();	
               Iterator iter3 =	
                  child2.getChildElements();	
               String content = child2.getValue();	
               System.out.println(content);	
               while (iter3.hasNext()) {	
                  SOAPElement child3 =	
                     (SOAPElement)iter3.next();	
                  Iterator iter4 =	
                        child3.getChildElements();	
                  content = child3.getValue();	
                  System.out.println(content);	
                  while (iter4.hasNext()) {	
                     SOAPElement child4 =	
                        (SOAPElement)iter4.next();	
                     content = child4.getValue();	
                     System.out.println(content);	
                  }	
               }	
            }   	
         }	
         connection.close();	
      } catch (Exception ex) { 	
         ex.printStackTrace(); 	
      }	
   }	
}
 

You are now ready to compile the code and move the new .class file to the directory myuddiping. If you have not already done so, you can copy the file MyUddiPing.java from <JWSDP_HOME>/docs/tutorial/examples/jaxm to <JWSDP_HOME>/samples/jaxm/myuddiping/src. When you execute the appropriate run script, which you will do next, it will compile MyUddiPing.java and move the resulting MyUddiPing.class file to the myuddiping directory for you.

To get a description of, for instance, Oracle, go to the myuddiping directory, and execute the appropriate run script as follows:


Note: If the run script is not executable, you will need to make it executable.

Unix:

cd $JWSDP_HOME/samples/jaxm/myuddiping	
run.sh uddi.properties Oracle
 

Windows:

cd %JWSDP_HOME%\samples\jaxm\myuddiping	
run.bat uddi.properties Oracle
 

Here is the output that will appear after the full XML message. It is produced by the code added in MyUddiPing.java.

Content extracted from the reply message: 
 
Oracle	
oracle powers the internet
 
Oracle Corporation	
Oracle Corporation provides the software and services for e-
business.
 

Running the script with Microsoft instead of Oracle produces the following output:

Received reply from: http://www-
3.ibm.com/services/uddi/testregistry/inquiryapi	
<?xml version="1.0" encoding="UTF-8" ?><Envelope 
xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body><busin
essList generic="1.0" xmlns="urn:uddi-org:api" 
operator="www.ibm.com/services/uddi" 
truncated="false"><businessInfos><businessInfo 
businessKey="D7475060-BF58-11D5-A432-
0004AC49CC1E"><name>Microsoft Corporation</name><description 
xml:lang="en">Computer Software and Hardware 
Manufacturer</description><serviceInfos></serviceInfos></busin
essInfo></businessInfos></businessList></Body></Envelope>
 
Content extracted from the reply message: 
 
Microsoft Corporation	
Computer Software and Hardware Manufacturer
 

Conclusion

JAXM provides a Java API that simplifies writing and sending XML messages. You have learned how to use this API to write client code for JAXM request-response messages and one-way messages. You have also learned how to get the content from a reply message. Finally, you have seen how to write and run your own modification of the uddiping sample application. You now have first-hand experience of how JAXM makes it easier to do XML messaging.

Home
TOC
PREV TOP NEXT