|
Download
FAQ History |
|
API
Search Feedback |
Code Examples
The first part of this tutorial uses code fragments to walk you through the fundamentals of using the SAAJ API. In this section, you will use some of those code fragments to create applications. First, you will see the program
Request.java. Then you will see how to run the programsMyUddiPing.java,HeaderExample.java,DOMExample.java,DOMSrcExample.java,Attachments.java, andSOAPFaultTest.java.You do not have to start the Sun Java System Application Server Platform Edition 8 in order to run these examples.
Request.java
The class
Request.javaputs together the code fragments used in the section Tutorial and adds what is needed to make it a complete example of a 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 java.util.*; import java.net.URL; public class Request { public static void main(String[] args) { try { SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection connection = soapConnectionFactory.createConnection(); SOAPFactory soapFactory = SOAPFactory.newInstance(); MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage();SOAPHeader header = message.getSOAPHeader();SOAPBody body = message.getSOAPBody(); header.detachNode(); Name bodyName = soapFactory.createName( "GetLastTradePrice", "m", "http://wombats.ztrade.com"); SOAPBodyElement bodyElement = body.addBodyElement(bodyName); Name name = soapFactory.createName("symbol"); SOAPElement symbol = bodyElement.addChildElement(name); symbol.addTextNode("SUNW"); URL endpoint = new URL ("http://wombat.ztrade.com/quotes"); SOAPMessage response = connection.call(message, endpoint); connection.close(); SOAPBody soapBody = response.getSOAPBody(); Iterator iterator = soapBody.getChildElements(bodyName); SOAPBodyElement bodyElement = (SOAPBodyElement)iterator.next(); String lastPrice = bodyElement.getValue(); System.out.print("The last price for SUNW is "); System.out.println(lastPrice); } catch (Exception ex) { ex.printStackTrace(); } } }For
Request.javato be runnable, the second argument supplied to thecallmethod would have to be a valid existing URI, and this is not true in this case. However, the application in the next section is one that you can run.MyUddiPing.java
The program
MyUddiPing.javais another example of a SAAJ client application. It sends a request to a Universal Description, Discovery and Integration (UDDI) service and gets back the response. A UDDI service is a business registry and repository from which you can get information about businesses that have registered themselves with the registry service. For this example, the MyUddiPing 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, MyUddiPing demonstrates a request being sent and a response being received.Setting Up
The MyUddiPing example is in the following directory:
Note:
<INSTALL>is the directory where you installed the tutorial bundle.
In the
myuddipingdirectory, you will find two files and thesrcdirectory. Thesrcdirectory contains one source file,MyUddiPing.java.The file
uddi.propertiescontains the URL of the destination (a UDDI test registry) and the proxy host and proxy port of the sender. By default, the destination is the IBM test registry; the Microsoft test registry is commented out.If you access the Internet from behind a firewall, edit the
uddi.propertiesfile to supply the correct proxy host and proxy port. If you are not sure what the values for these are, consult your system administrator or another person with that information. The typical value of the proxy port is 8080. You can also edit the file to specify another registry.The file
build.xmlis theasantbuild file for this example. It includes the file<INSTALL>/j2eetutorial14/examples/saaj/common/targets.xml, which contains a set of targets common to all the SAAJ examples.The
preparetarget creates a directory namedbuild. To invoke thepreparetarget, you type the following at the command line:The target named
buildcompiles the source fileMyUddiPing.javaand puts the resulting.classfile in thebuilddirectory. So to do these tasks, you type the following at the command line:Examining MyUddiPing
We will go through the file
MyUddiPing.javaa few lines at a time, concentrating on the last section. This is the part of the application that accesses only the content you want from the XML message returned by the UDDI registry.The first few lines of code import the packages used in the application.
The next few lines begin the definition of the class
MyUddiPing, which starts with the definition of itsmainmethod. The first thing it does is to check to see whether two arguments were supplied. If they were not, it prints a usage message and exits. The usage message mentions only one argument; the other is supplied by thebuild.xmltarget.public class MyUddiPing { public static void main(String[] args) { try { if (args.length != 2) { System.err.println("Argument required: " + "-Dbusiness-name=<name>"); System.exit(1); }The following lines create a
java.util.Propertiesobject that contains the system properties and the properties from the fileuddi.properties, which is in themyuddipingdirectory.Properties myprops = new Properties(); myprops.load(new FileInputStream(args[0])); Properties props = System.getProperties(); Enumeration enum = myprops.propertyNames(); while (enum.hasMoreElements()) { String s = (String)enum.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 soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection connection = soapConnectionFactory.createConnection(); MessageFactory messageFactory = MessageFactory.newInstance(); SOAPMessage message = messageFactory.createMessage();The next lines of code retrieve the
SOAPHeaderandSOAPBodyobjects from the message and remove the header.SOAPHeader header = message.getSOAPHeader(); SOAPBody body = message.getSOAPBody(); header.detachNode();The following lines of code create the UDDI
find_businessmessage. The first line gets aSOAPFactoryinstance that we will use to create names. The next line adds theSOAPBodyElementwith a fully qualified name, including the required namespace for a UDDI version 2 message. The next lines add two attributes to the new element: the required attributegeneric, with the UDDI version number 2.0, and the optional attributemaxRows, with the value 100. Then the code adds a child element that has theNameobjectnameand adds text to the element by using the methodaddTextNode. The added text is the business name you will supply at the command line when you run the application.SOAPFactory soapFactory = SOAPFactory.newInstance(); SOAPBodyElement findBusiness = body.addBodyElement(soapFactory.createName( "find_business", "", "urn:uddi-org:api_v2")); findBusiness.addAttribute(soapFactory.createName( "generic"), "2.0"); findBusiness.addAttribute(soapFactory.createName( "maxRows"), "100"); SOAPElement businessName = findBusiness.addChildElement( soapFactory.createName("name")); businessName.addTextNode(args[1]);The next 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.
The following lines display the message that will be sent:
The next line of code creates the
java.net.URLobject that represents the destination for this message. It gets the value of the property namedURLfrom the system property file.Next, the message
messageis sent to the destination thatendpointrepresents, which is the UDDI test registry. Thecallmethod will block until it gets aSOAPMessageobject back, at which point it returns the reply.In the next lines of code, the first line prints a line giving the URL of the sender (the test registry), and the others display the returned message.
System.out.println("\n\nReceived reply from: " + endpoint); System.out.println("\n---- Reply Message ----\n"); reply.writeTo(System.out);The returned message is the complete SOAP message, an XML document, as it looks when it comes over the wire. It is a
businessListthat follows the format specified inhttp://uddi.org/pubs/DataStructure-V2.03-Published-20020719.htm#_Toc25130802.As interesting as it is to see the XML that is actually transmitted, the XML document format does not make it easy to see the text that is the message's content. To remedy this, the last part of
MyUddiPing.javacontains code that prints only the text content of the response, making it much easier to see the information you want.Because the content is in the
SOAPBodyobject, the first step is to access it, as shown in the following line of code.Next, the code displays a message describing the content:
To display the content of the message, the code uses the known format of the reply message. First, it gets all the reply body's child elements named
businessList:Iterator businessListIterator = replyBody.getChildElements( soapFactory.createName("businessList", "", "urn:uddi-org:api_v2"));The method
getChildElementsreturns the elements in the form of ajava.util.Iteratorobject. You access the child elements by calling the methodnexton theIteratorobject. An immediate child of aSOAPBodyobject is aSOAPBodyElementobject.We know that the reply can contain only one
businessListelement, so the code then retrieves this one element by calling the iterator'snextmethod. Note that the methodIterator.nextreturns anObject, which must be cast to the specific kind of object you are retrieving. Thus, the result of callingbusinessListIterator.nextis cast to aSOAPBodyElementobject:The next element in the hierarchy is a single
businessInfoselement, so the code retrieves this element in the same way it retrieved thebusinessList. Children ofSOAPBodyElementobjects and all child elements from this point forward areSOAPElementobjects.Iterator businessInfosIterator = businessList.getChildElements( soapFactory.createName("businessInfos", "", "urn:uddi-org:api_v2")); SOAPElement businessInfos = (SOAPElement)businessInfosIterator.next();The
businessInfoselement contains zero or morebusinessInfoelements. If the query returned no businesses, the code prints a message saying that none were found. If the query returned businesses, however, the code extracts the name and optional description by retrieving the child elements that have those names. The methodIterator.hasNextcan be used in awhileloop because it returnstrueas long as the next call to the methodnextwill return a child element. Accordingly, the loop ends when there are no more child elements to retrieve.Iterator businessInfoIterator = businessInfos.getChildElements( soapFactory.createName("businessInfo", "", "urn:uddi-org:api_v2")); if (! businessInfoIterator.hasNext()) { System.out.println("No businesses found " + "matching the name '" + args[1] + "'."); } else { while (businessInfoIterator.hasNext()) { SOAPElement businessInfo = (SOAPElement) businessInfoIterator.next(); // Extract name and description from the // businessInfo Iterator nameIterator = businessInfo.getChildElements( soapFactory.createName("name", "", "urn:uddi-org:api_v2")); while (nameIterator.hasNext()) { businessName = (SOAPElement)nameIterator.next(); System.out.println("Company name: " + businessName.getValue()); } Iterator descriptionIterator = businessInfo.getChildElements( soapFactory.createName( "description", "", "urn:uddi-org:api_v2")); while (descriptionIterator.hasNext()) { SOAPElement businessDescription = (SOAPElement) descriptionIterator.next(); System.out.println("Description: " + businessDescription.getValue()); } System.out.println(""); }Running MyUddiPing
Make sure you have edited the
uddi.propertiesfile and compiledMyUddiPing.javaas described in Setting Up.With the code compiled, you are ready to run MyUddiPing. The
runtarget takes two arguments, but you need to supply only one of them. The first argument is the fileuddi.properties, which is supplied by a property set inbuild.xml. The other 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 any value set for that property in thebuild.xmlfile.Use the following command to run the example:
Output similar to the following will appear after the full XML message:
Content extracted from the reply message: Company name: Food Description: Test Food Company name: Food Manufacturing Company name: foodCompanyA Description: It is a food company sells biscuitIf you want to run MyUddiPing again, you may want to start over by deleting the
builddirectory and the.classfile it contains. You can do this by typing the following at the command line:HeaderExample.java
The example
HeaderExample.java, based on the code fragments in the section Adding Attributes, creates a message that has several headers. It then retrieves the contents of the headers and prints them. You will find the code forHeaderExamplein the following directory:Running HeaderExample
To run HeaderExample, you use the file
build.xmlthat is in the directory <INSTALL>/j2eetutorial14/examples/saaj/headers/.To run HeaderExample, use the following command:
This command executes the
prepare,build, andruntargets in thebuild.xmlandtargets.xmlfiles.When you run HeaderExample, you will see output similar to the following:
----- Request Message ---- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header> <ns:orderDesk SOAP-ENV:actor="http://gizmos.com/orders" xmlns:ns="http://gizmos.com/NSURI"/> <ns:shippingDesk SOAP-ENV:actor="http://gizmos.com/shipping" xmlns:ns="http://gizmos.com/NSURI"/> <ns:confirmationDesk SOAP-ENV:actor="http://gizmos.com/confirmations" xmlns:ns="http://gizmos.com/NSURI"/> <ns:billingDesk SOAP-ENV:actor="http://gizmos.com/billing" xmlns:ns="http://gizmos.com/NSURI"/> <t:Transaction SOAP-ENV:mustUnderstand="1" xmlns:t="http:// gizmos.com/orders">5</t:Transaction> </SOAP-ENV:Header><SOAP-ENV:Body/></SOAP-ENV:Envelope> Header name is ns:orderDesk Actor is http://gizmos.com/orders mustUnderstand is false Header name is ns:shippingDesk Actor is http://gizmos.com/shipping mustUnderstand is false Header name is ns:confirmationDesk Actor is http://gizmos.com/confirmations mustUnderstand is false Header name is ns:billingDesk Actor is http://gizmos.com/billing mustUnderstand is false Header name is t:Transaction Actor is null mustUnderstand is trueDOMExample.java and DOMSrcExample.java
The examples
DOMExample.javaandDOMSrcExample.javashow how to add a DOM document to a message and then traverse its contents. They show two ways to do this:You will find the code for DOMExample and DOMSrcExample in the following directory:
Examining DOMExample
DOMExample first creates a DOM document by parsing an XML document, almost exactly like the JAXP example
DomEcho01.javain the directory <INSTALL>/j2eetutorial14/examples/jaxp/dom/samples/. The file it parses is one that you specify on the command line.static Document document; ... DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse( new File(args[0]) ); ...Next, the example creates a SOAP message in the usual way. Then it adds the document to the message body:
This example does not change the content of the message. Instead, it displays the message content and then uses a recursive method,
getContents, to traverse the element tree using SAAJ APIs and display the message contents in a readable form.public void getContents(Iterator iterator, String indent) { while (iterator.hasNext()) { SOAPElement element = (SOAPElement)iterator.next(); Name name = element.getElementName(); System.out.println(indent + "Name is " + name.getQualifiedName()); String content = element.getValue(); if (content != null) { System.out.println(indent + "Content is " + content); } Iterator attrs = element.getAllAttributes(); while (attrs.hasNext()){ Name attrName = (Name)attrs.next(); System.out.println(indent + " Attribute name is " + attrName.getQualifiedName()); System.out.println(indent + " Attribute value is " + element.getAttributeValue(attrName)); } if (content == null) { Iterator iter2 = element.getChildElements(); getContents(iter2, indent + " "); } } }Examining DOMSrcExample
DOMSrcExample differs from DOMExample in only a few ways. First, after it parses the document, DOMSrcExample uses the document to create a
DOMSourceobject. This code is the same as that of DOMExample except for the last line:static DOMSource domSource; ... try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse( new File(args[0]) ); domSource = new DOMSource(document); ...Then, after DOMSrcExample creates the message, it does not get the header and body and add the document to the body, as DOMExample does. Instead, DOMSrcExample gets the SOAP part and sets the
DOMSourceobject as its content:// Create a message SOAPMessage message = messageFactory.createMessage(); // Get the SOAP part and set its content to domSource SOAPPart soapPart = message.getSOAPPart(); soapPart.setContent(domSource);The example then uses the
getContentsmethod to obtain the contents of both the header (if it exists) and the body of the message.The most important difference between these two examples is the kind of document you can use to create the message. Because DOMExample adds the document to the body of the SOAP message, you can use any valid XML file to create the document. But because DOMSrcExample makes the document the entire content of the message, the document must already be in the form of a valid SOAP message, and not just any XML document.
Running DOMExample and DOMSrcExample
To run DOMExample and DOMSrcExample, you use the file
build.xmlthat is in the directory <INSTALL>/j2eetutorial14/examples/saaj/dom/. This directory also contains several sample XML files you can use:
domsrc1.xml, an example that has a SOAP header (the contents of theHeaderExampleoutput) and the body of a UDDI querydomsrc2.xml, an example of a reply to a UDDI query (specifically, some sample output from the MyUddiPing example), but with spaces added for readabilityuddimsg.xml, similar todomsrc2.xmlexcept that it is only the body of the message and contains no spacesslide.xml, similar to theslideSample01.xmlfile in <INSTALL>/j2eetutorial14/examples/jaxp/dom/samples/To run DOMExample, use a command like the following:
After running DOMExample, you will see output something like the following:
Running DOMExample. Name is businessList Attribute name is generic Attribute value is 2.0 Attribute name is operator Attribute value is www.ibm.com/services/uddi Attribute name is truncated Attribute value is false Attribute name is xmlns Attribute value is urn:uddi-org:api_v2 ...To run DOMSrcExample, use a command like the following:
When you run DOMSrcExample, you will see output that begins like the following:
run-domsrc: Running DOMSrcExample. Body contents: Content is: Name is businessList Attribute name is generic Attribute value is 2.0 Attribute name is operator Attribute value is www.ibm.com/services/uddi Attribute name is truncated Attribute value is false Attribute name is xmlns Attribute value is urn:uddi-org:api_v2 ...If you run DOMSrcExample with the file
uddimsg.xmlorslide.xml, you will see runtime errors.Attachments.java
The example
Attachments.java, based on the code fragments in the sections Creating an AttachmentPart Object and Adding Content and Accessing an AttachmentPart Object, creates a message that has a text attachment and an image attachment. It then retrieves the contents of the attachments and prints the contents of the text attachment. You will find the code for Attachments in the following directory:Attachments first creates a message in the usual way. It then creates an
AttachmentPartfor the text attachment:After it reads input from a file into a string named
stringContent, it sets the content of the attachment to the value of the string and the type totext/plainand also sets a content ID.It then adds the attachment to the message:
The example uses a
javax.activation.DataHandlerobject to hold a reference to the graphic that constitutes the second attachment. It creates this attachment using the form of thecreateAttachmentPartmethod that takes aDataHandlerargument.// Create attachment part for image URL url = new URL("file:///./xml-pic.jpg"); DataHandler dataHandler = new DataHandler(url); AttachmentPart attachment2 = message.createAttachmentPart(dataHandler); attachment2.setContentId("attached_image"); message.addAttachmentPart(attachment2);The example then retrieves the attachments from the message. It displays the
contentIdandcontentTypeattributes of each attachment and the contents of the text attachment.Running Attachments
To run Attachments, you use the file
build.xmlthat is in the directory <INSTALL>/j2eetutorial14/examples/saaj/attachments/.To run Attachments, use the following command:
Specify any text file as the
path_nameargument. Theattachmentsdirectory contains a file namedaddr.txtthat you can use:When you run Attachments using this command line, you will see output like the following:
Running Attachments. Attachment attached_text has content type text/plain Attachment contains: Update address for Sunny Skies, Inc., to 10 Upbeat Street Pleasant Grove, CA 95439 Attachment attached_image has content type image/jpegSOAPFaultTest.java
The example
SOAPFaultTest.java, based on the code fragments in the sections Creating and Populating a SOAPFault Object and Retrieving Fault Information, creates a message that has aSOAPFaultobject. It then retrieves the contents of theSOAPFaultobject and prints them. You will find the code for SOAPFaultTest in the following directory:Running SOAPFaultTest
To run SOAPFaultTest, you use the file
build.xmlthat is in the directory <INSTALL>/j2eetutorial14/examples/saaj/fault/.To run SOAPFaultTest, use the following command:
When you run SOAPFaultTest, you will see output like the following (line breaks have been inserted in the message for readability):
Here is what the XML message looks like: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/><SOAP-ENV:Body> <SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode> <faultstring>Message does not have necessary info</faultstring> <faultactor>http://gizmos.com/order</faultactor> <detail> <PO:order xmlns:PO="http://gizmos.com/orders/"> Quantity element does not have a value</PO:order> <PO:confirmation xmlns:PO="http://gizmos.com/confirm"> Incomplete address: no zip code</PO:confirmation> </detail></SOAP-ENV:Fault> </SOAP-ENV:Body></SOAP-ENV:Envelope> SOAP fault contains: Fault code = SOAP-ENV:Client Local name = Client Namespace prefix = SOAP-ENV, bound to http://schemas.xmlsoap.org/soap/envelope/ Fault string = Message does not have necessary info Fault actor = http://gizmos.com/order Detail entry = Quantity element does not have a value Detail entry = Incomplete address: no zip code
|
Download
FAQ History |
|
API
Search Feedback |
All of the material in The J2EE(TM) 1.4 Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.