|
Home TOC |
|
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.javaand also creates the applicationMyUddiPing.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.javais shown here and is also included in the<JWSDP_HOME>/docs/tutorial/examples/jaxmdirectory. 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 addsimportstatements, amainmethod, and atry/catchblock 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.javato be runnable, theURLEndpointobject 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.javais 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, theUddiPingapplication 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,UddiPingdemonstrates 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 rewriteUddiPing.javaso 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
UddiPingexample, take a look at the directory<JWSDP_HOME>/samples/jaxm/uddiping. This directory contains the subdirectorysrcand the filesrun.sh,uddi.properties,UddiPing.class, andREADME. TheREADMEfile tells you what you need to do to run the application, which is explained more fully here.The
READMEfile directs you to modify the filebuild.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 theuddipingdirectory when you call therun.shscript, the information in therunscript should be correct already.The
run.shscript calls thejavacommand onUddiPing. First it sets the location of thejavacommand 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.jarfiles 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 OracleExecuting the
runscript 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 toUddiPing.javathat extracts the content so that it is readily visible.Creating MyUddiPing.java
To make the response to
UddiPing.javaeasier to read, you will create a new file calledMyUddiPing.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 isMyUddiPing.java, you need to create the directorymyuddipingunder the<JWSDP_HOME>/samples/jaxmdirectory. Then copy all of the files from theuddipingdirectory into themyuddipingdirectory.cd $JWSDP_HOME/samples/jaxm mkdir myuddiping cp uddiping/* myuddipingOpen
run.shand changeUddiPingtoMyUddiPingso that therunscript will be called on the correct file.The
MyUddiPing.classfile will be added to the directorymyuddipingas part of the execution of therun.shscript. Therun.shscript will be examined more later.The
srcdirectory will not have been copied fromuddipingbecause it is not a file, so you need to create your ownsrcdirectory. Then go to thesrcdirectory and create the fileMyUddiPing.javausing your favorite editor.cd myuddiping mkdir srcFor convenience, you can copy
MyUddiPing.javafrom theexamplesdirectory to your newsrcdirectory as follows:cd $JWSDP_HOME/docs/tutorial/examples/jaxm cp MyUddiPing.java $JWSDP_HOME/samples/jaxm/myuddiping/srccd %JWSDP_HOME%\docs\tutorial\examples\jaxm cp MyUddiPing.java %JWSDP_HOME%\samplels\jaxm\myuddiping\srcNow let's go through the file a few lines at a time. Note that most of the class
MyUddiPing.javais based onUddiPing.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 methodcall.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 itsmainmethod. 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 therunscripts 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.Propertiesfile that contains the system properties and the properties from the fileuddi.propertiesthat is in themyuddipingdirectory.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
SOAPMessageobject. First, the code gets an instance ofSOAPConnectionFactoryand uses it to create a connection. Then it gets an instance ofMessageFactoryand uses it to create a message.SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance(); SOAPConnection connection = scf.createConnection(); MessageFactory msgFactory = MessageFactory.newInstance(); SOAPMessage msg = msgFactory.createMessage();The new
SOAPMessageobjectmsgautomatically contains aSOAPPartobject that contains aSOAPEnvelopeobject. TheSOAPEnvelopeobject contains aSOAPBodyobject, which is the element you want to access in order to add content to it. The next lines of code get theSOAPPartobject, theSOAPEnvelopeobject, and theSOAPBodyobject.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 namenameand adds some text to it with the methodaddTextNode. The text added is theStringobject 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
URLEndpointobject 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
msgis sent to the destination thatendpointrepresents, which is the test UDDI registry. The methodcallwill block until it gets aSOAPMessageobject 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 theuddipingdirectory and call the appropriaterunscript, you can see what the output looks like.cd $JWSDP_HOME/samples/jaxm/uddiping run.sh uddi.properties Microsoftcd %JWSDP_HOME%\samples\jaxm\uddiping run.bat uddi.properties MicrosoftWhat 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
SOAPBodyobject, 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 theSOAPBodyobject 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
SOAPElementmethodgetChildElements. 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 theNameobject used to name an element, you can supply that togetChildElementsand 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
getChildElementsreturns the elements in the form of ajava.util.Iteratorobject. You access the child elements by calling the methodnexton theIteratorobject. The methodIterator.hasNextcan be used in awhileloop because it returnstrueas long as the next call to the methodnextwill return a child element. The loop ends when there are no more child elements to retrieve.An immediate child of a
SOAPBodyobject is aSOAPBodyElementobject, which is why callingiter1.nextreturns aSOAPBodyElementobject. Children ofSOAPBodyElementobjects and all child elements from there down areSOAPElementobjects. For example, the calliter2.nextreturns theSOAPElementobjectchild2. Note that the methodIterator.nextreturns anObject, which has to be narrowed (cast) to the specific kind of object you are retrieving. Thus, the result of callingiter1.nextis cast to aSOAPBodyElementobject, whereas the results of callingiter2.next,iter3.next, and so on, are allcast to aSOAPElementobject.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
.classfile to the directorymyuddiping. If you have not already done so, you can copy the fileMyUddiPing.javafrom<JWSDP_HOME>/docs/tutorial/examples/jaxmto<JWSDP_HOME>/samples/jaxm/myuddiping/src. When you execute the appropriaterunscript, which you will do next, it will compileMyUddiPing.javaand move the resultingMyUddiPing.classfile to themyuddipingdirectory for you.To get a description of, for instance, Oracle, go to the
myuddipingdirectory, and execute the appropriaterunscript as follows:
Note: If therunscript is not executable, you will need to make it executable.
cd $JWSDP_HOME/samples/jaxm/myuddiping run.sh uddi.properties Oraclecd %JWSDP_HOME%\samples\jaxm\myuddiping run.bat uddi.properties OracleHere 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 ManufacturerConclusion
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
uddipingsample application. You now have first-hand experience of how JAXM makes it easier to do XML messaging.
|
Home TOC |
|