JaVa
   

SAAJ

SOAP with Attachments API for Java (SAAJ) is defined to enable apps to take advantage of the SOAP protocol. It defines a Java API for producing, consuming, and manipulating SOAP messages that conform to the SOAP 1.1 specification and SOAP with Attachments note. SAAJ was created as part of the Java API for XML messaging (JAXM) under JSR-67 but was refactored into its own specification, because all the other JAX APIs used it. It made sense to have this common API stand on its own. Let us now take a closer look at SAAJ.

SAAJ provides a level of abstraction that insulates developers from low-level manipulation of angle brackets. Developers create and work with Java classes in the javax.xml.soap package that model different XML elements in a SOAP message and the semantics of connecting and sending SOAP messages. The API relevant to modeling the SOAP message is shown in Screenshot and explained in Table 4.1.

Table 4.1: The Object Representation of a SOAP Message in SAAJ

AttachmentPart

Models the attachment in a SOAP message.

MimeHeader

An object that stores a MIME header name and its value.

MimeHeaders

A container for MimeHeader objects, which represent the MIME headers present in a MIME part of a message.

Node

The base interface that represents an XML element. Though it is analogous to the Node in the W3C DOM discussed in , it is not the same.

SOAPBody

Models the body from a SOAP message.

SOAPBodyElement

Represents the contents in a SOAPBody object.

SOAPElement

Subclasses Node to provide the base functionality for all classes that represent SOAP objects defined in the SOAP specification.

SOAPEnvelope

Models the envelope in a SOAP message.

SOAPFault

Models a fault and is contained in a SOAPBody object.

SOAPFaultElement

A representation of the contents in a SOAPFault object.

SOAPHeader

Models the header element of the SOAP message

SOAPHeaderElement

Models individual header elements in a SOAPHeader.

SOAPMessage

The root class for all SOAP messages.

SOAPPart

The container for the SOAP-specific portion of a SOAPMessage object.

Java Click To expand
Screenshot: The SAAJ object model

Each part of the SOAP message discussed in this chapter is modeled in SAAJ as a Java class or interface developers can work with in their code. Though Screenshot is self-explanatory, there are two other classes in SAAJ are important. Like the rest of the API that abstracts the SOAP message, these classes abstract the semantics relating to a request-response-based transmission of the message:

To understand how SAAJ works, let us put everything together with an example of this API in action. The BillPay service exposes a Java method with the following syntax:

PaymentConfirmation schedulePayment(Date date, String nickName, doubleamount);


Listing 4.6 shows the SOAP request this Web service expects. We will put aside the part about how the service is implemented until . Listing 4.7 shows the SAAJ code, and Listing 4.8 shows the SOAP response that the service returns. The client code takes the following sequence:

  1. Instantiate the MessageFactory.

  2. Create an empty SOAPMessage from the factory.
  3. Access the SOAPEnvelope from the message.
  4. Access the SOAPBody from the envelope.
  5. Create the elements in the body and save the changes to the message.
  6. Create a SOAPConnection object from a SOAPConnectionFactory.
  7. Send the SOAPMessage to the endpoint, using the connection.
Listing 4.6: The SOAP request message
<?xml version="1.0" encoding="UTF-8"?>
 <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:ns0="http://www.flutebank.com/xml"
 env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <env:Body>
 <ns0:schedulePayment>
 <Date_1 xsi:type="xsd:dateTime">2002-10-05T04:49:26.769Z</Date_1>
 <String_2 xsi:type="xsd:string">my account at sprint</String_2>
 <double_3 xsi:type="xsd:double">190.0</double_3>
 </ns0:schedulePayment>
 </env:Body>
</env:Envelope>



Java End example
Listing 4.7: A SAAJ client for constructing and sending a SOAP message
import javax.xml.soap.*;
import java.util.Iterator;
import java.util.Date;
import java.text.SimpleDateFormat;
import javax.xml.messaging.URLEndpoint;
public class SAAJClient{
/** Class to demonstrate how to send a soap message synchronously with SAAJ API. */
 public static void main(String args[]) throws Exception {
 String url = "http://127.0.0.1:9090/billpayservice/jaxrpc/BillPay";
 if (args.length > 0)
 url = args[0];
// Construct a default SOAP message factory.
 MessageFactory mfactory = MessageFactory.newInstance();
// Create an empty message
 SOAPMessage message = mfactory.createMessage();
 SOAPPart soap = message.getSOAPPart();
// Access the envelope
 SOAPEnvelope envelope = soap.getEnvelope();
 envelope.addNamespaceDeclaration("xmlns:xsd"," http://www.w3.org/2001/
 XMLSchema");
 envelope.addNamespaceDeclaration("xmlns:xsi",
 "http://www.w3.org/2001/XMLSchema-instance" );
 envelope.addNamespaceDeclaration("xmlns:ns0"," http://www.flutebank.com/xml" );
 envelope.setEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/");
// Access the body
 SOAPBody body = envelope.getBody();
 Name name = envelope.createName("schedulePayment", "ns0",
 "http://www.flutebank.com/xml");
 SOAPBodyElement element = body.addBodyElement(name);
// create a name for the attribute name that can be reused
 Name xsitype = envelope.createName("xsi:type");
// create the Date_1 element
 Name dateelement = envelope.createName("Date_1");
 SOAPElement date = element.addChildElement(dateelement);
 date.addAttribute(xsitype," xsd:dateTime");
// Format the Java Date object in the syntax that is compliant with the XML schema
 SimpleDateFormat dateFormatter
 new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
 String xmldate=dateFormatter.format(new Date()).toString();
 date.addTextNode(xmldate);
// create the String_2 element
 Name strelement = envelope.createName("String_2");
 SOAPElement str = element.addChildElement(strelement);
 str.addAttribute(xsitype," xsd:string");
 str.addTextNode("my account at string");
// create the double_3 element
 name dblelement = envelope.createName("double_3");
 SOAPElement dbl = element.addChildElement(dblelement);
 dbl.addAttribute(xsitype," xsd:double");
 dbl.addTextNode("190.0");
// save changes to the message
 message.saveChanges();
 // Construct a default SOAP connection factory.
 SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
 // Get SOAP connection.
 SOAPConnection connection = factory.createConnection();
 // Construct endpoint object.
 URLEndpoint endpoint = new URLEndpoint(url);
// Send SOAP message.
 SOAPMessage response = connection.call(message, endpoint);
// process the return message
 SOAPPart sp = response.getSOAPPart();
 SOAPEnvelope se = sp.getEnvelope();
 SOAPBody sb = se.getBody();
 Iterator it = sb.getChildElements();
 while (it.hasNext()) {
 SOAPBodyElement bodyElement = (SOAPBodyElement)it.next();
 System.out.println(bodyElement.getElementName().getQualifiedName() + "
 namepace uri="+bodyElement.getElementName().getURI());
 Iterator it2 = bodyElement.getChildElements();
 while (it2.hasNext()) {
 SOAPElement element2 = (SOAPElement)it2.next();
 System.out.print(element2.getElementName().getQualifiedName() +" = ");
 System.out.println(element2.getValue());
 }
 }
 //Debug method, Print response to the std output
 System.out.println("\n\n\n Dumping complete message \n\n---------------\n\n");
 response.writeTo(System.out);
 // close the connection
 connection.close();
 }
}




Java End example
Listing 4.8: The SOAP response from the service
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:ns0="http://www.flutebank.com/xml"
 env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <env:Body>
 <ns0:schedulePaymentResponse>
 <result href="#id1"/>
 </ns0:schedulePaymentResponse>
 <ns0:PaymentConfirmation xsi:type="ns0:PaymentConfirmation">
 <confirmationNum xsi:type="xsd:int">81263767</confirmationNum>
 <payee xsi:type="xsd:string">Sprint PCS</payee>
 <amt xsi:type="xsd:double">190.0</amt>
 </ns0:PaymentConfirmation>
 </env:Body>
</env:Envelope>



Java End example

Though we have seen how a SOAP request and response can be constructed and sent using SAAJ, the preceding example was meant more as an insight into the workings of SAAJ. We don't envision direct use of this API by developers, because it is unlikely visual inspection of a SOAP request would be necessary. Other APIs, such as JAXM and JAX-RPC, abstract away this usage with higher-level constructs and with tools to interpret the SOAP service descriptions in a WSDL file. SAAJ is more likely to form the underpinnings of these high-level constructs in different vendor implementations. We will talk more about SAAJ and this type of request-response communication in .


JaVa
   
Comments