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. In this section, you will use some of those code fragments to create the program Request.java and also create 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 puts together the code fragments in the previous section and adds the elements needed to make it a complete example of a 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. The file Request.java, shown here in its entirety, will be discussed in more detail following the file.

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. For this example, 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 (or run.bat), 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 uddi.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 (or run.bat) 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 subdirectories and files.

Setting Up

Because the name of the new file is MyUddiPing.java, create the directory myuddiping under the <JWSDP_HOME>/samples/jaxm directory.

cd $JWSDP_HOME/samples/jaxm	
mkdir myuddiping
 

This new directory will be the base directory for all future commands in this tutorial.

In place of the run.sh or run.bat script used for running UddiPing, you will be using an Ant file, build.xml, for setting up directories and files and for running MyUddiPing. The advantage of using an Ant file is that it is cross-platform and can thus be used for both Unix and Windows platforms. Accordingly, you need to copy the build.xml file in the examples/jaxm directory of the tutorial to your new myuddiping directory.

Unix:

cd myuddiping	
cp $JWSDP_HOME/docs/tutorial/examples/jaxm/build.xml .
 

Windows:

cd myuddiping	
copy %JWSDP_HOME%\docs\tutorial\examples\jaxm\build.xml .
 

Once you have the file build.xml in your myuddiping directory, you can call it to do the rest of the setup and also to run MyUddiPing. An Ant build file is an XML file that is sectioned into targets, with each target being an element that contains attributes and one or more tasks. For example, the target element whose name attribute is prepare creates the directories build and src and copies the file MyUddiPing.java from the <JWSDP_HOME>/docs/tutorial/examples/jaxm directory to the new src directory. Then it copies the file uddi.properties from the uddiping directory to the myuddiping directory that you created.

To accomplish these tasks, you type the following at the command line:

ant prepare
 

The target named build compiles the source file MyUddiPing.java and puts the resulting .class file in the build directory. So to do these tasks, you type the following at the command line:

ant build
 

Now that your are set up for running MyUddiPing, let's take a closer look at the code.

Examining MyUddiPing

We will go through the file MyUddiPing.java 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 of MyUddiPing.java 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.

public class MyUddiPing {	
   public static void main(String[] args) {	
      try {	
         if (args.length != 2) {	
            System.err.println("Usage: MyUddiPing " +	
               "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. The README file in the uddiping directory instructs you to modify the properties in the file uddi.properties as necessary. If you are calling the run script from within Sun Microsystem's firewall, you do not need to make any modifications. If you are outside the firewall, you need to supply your proxy host and proxy port. If you are not sure what the values for these are, you need to consult your system administrator or other person with that information.

Once the file uddi.properties has the correct proxy host and proxy port, you can call the appropriate run script as shown here. Note that the run scripts take two arguments, uddi.properties and the name of the business you want to look up.

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. Note that by contrast, the entries in a standard valid registry will be consistent.

The code you will be adding drills down through the subelements within the SOAP body and retrieves the name and description of the business. 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 example, 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 business 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 have already compiled MyUddiPing.java by calling the following at the command line:

ant build
 

With the code compiled, you are ready to run MyUddiPing. The following command will call java on the .class file for MyUddiPing, which takes two arguments. The first argument is the file uddi.properties, which is supplied by a property set in build.xml. The second argument is the name of the business for which you want to get a description, and you need to supply this argument on the command line. Note that any property set on the command line overrides the value set for that property in the build.xml file. The last argument supplied to Ant is always the target, which in this case is run.

ant -Dbusiness-name="Oracle" run
 

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 Ant with Microsoft as the business-name property 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