You are on page 1of 19

03/09/2004

Agenda
? What is SAAJ?
? SOAP message structure
? SAAJ programming APIs
SAAJ ? SAAJ and DOM

(SOAP Attachment SAAJ service


?

? SAAJ error handling


API for Java)

1 5

SAAJ
? Contains the API for creating, populating, and
accessing SOAP messages conforming to
SOAP 1.1 and SOAP with Attachment
specifications

What is SAAJ? – Used within SOAP message handlers for


reading/modifying SOAP headers
? Contains API necessary for sending request-
response (non-provider-model) messages
? Separated out from JAXM 1.0 into JAXM 1.1
and SAAJ 1.1 (latest version is SAAJ 1.2)
6 7
03/09/2004

Package Relationship

javax.xml.rpc javax.xml.messaging

SOAP Message
SAAJ
Structure
javax.xml.soap

8 9

SOAP Message Structure


SOAP Message SOAP Envelope
with Attachments
SOAP Header
SOAP
Primary MIME part
(text/xml)
Header Entry Message
Header Entry
Object
Attachment Without
Attachment
SOAP Body
Attachments
Body Entry

Body Entry
Attachment

source: Java WSDP


10 11
03/09/2004

SOAP
Message
Object With SAAJ
Attachments Programming APIs
source: Java WSDP
12 13

javax.xml.soap Package: Interfaces


SAAJ Node
? javax.xml.soap.* package SOAPEnvelope

? SOAPConnection SOAPElement
– For request/response SOAP message exchange Text SOAPHeader

? SOAPMessage
– Creating and populating
SOAPHeaderElement
? Constituent parts of a SOAP message SOAPBody

– SOAPPart
– AttachmentPart
SOAPBodyElement SOAPFault

14 15
03/09/2004

javax.xml.soap Package: Classes javax.xml.soap.MessageFactory


MessageFactory SOAPPart SOAPElementFactory
? Factory for creating SOAP 1.1-based
messages
AttachmentPart
? Can add “default” or pre-configured
SOAPMessage
headers (based on Profiles) as part of
Exception
construction (JAXM)
SOAPConnection
SOAPConnection Factory SOAPException – Can return Message subclasses for particular
profiles

MimeHeader MimeHeaders

16 17

javax.xml.soap.SOAPMessage javax.xml.soap.SOAPPart
? Java technology abstraction for a SOAP ? The first part of a multi-part message
1.1 message when there are attachments
? SOAPPart + Zero or more ? Contains a SOAP 1.1 header
AttachmentPart's ? Support to create or examine the SOAP
1.1 header elements

18 19
03/09/2004

javax.xml.soap.AttachmentPart
? Can contain any data (for example:
JPEG images, XML business
documents, etc.)
– Must have a MIME header to indicate the type
of data it contains
Steps of SAAJ
? May also have additional MIME headers Programming
to identify it or to give its location, which
are optional but can be useful when
there are multiple attachments
20 21

Steps Creating a Message


? Creating a message (SOAPMessage) ? Use MessageFactory to as a factory of messages
? Accessing elements of a message ? SOAPMessage object has the following

? Adding contents to the body 1 SOAPPart object
? 1 SOAPEnvelope object
? Getting a SOAPConnection object – 1 empty SOAPHeader object
? Sending a message – 1 empty SOAPBody object
? Getting the content of a message ? Example
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();

22 23
03/09/2004

XML Fragment Accessing SOAPHeader &


SOAPBody
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> ? Approach 1: from SOAPHeader object
<SOAP-ENV:Header/> SOAPPart soapPart = message.getSOAPPart();
<SOAP-ENV:Body>
SOAPEnvelope envelope = soapPart.getEnvelope();
</SOAP-ENV:Body>
</SOAP-ENV:Envelope> SOAPHeader header = envelope.getHeader();
SOAPBody body = envelope.getBody();
? Approach 2: from SOAPMessage object
SOAPHeader header = message.getSOAPHeader();
SOAPBody body = message.getSOAPBody();

24 25

Adding contents to the body Adding contents to the body


SOAPBody body = message.getSOAPBody();
SOAPFactory soapFactory = SOAPFactory.newInstance(); Name name = soapFactory.createName("symbol");
Name bodyName = soapFactory.createName("GetLastTradePrice", SOAPElement symbol = bodyElement.addChildElement(name);
"m", "http://wombat.ztrade.com"); symbol.addTextNode("SUNW");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
Generates XML fragment like following:
Generates XML fragment like following:
<symbol>SUNW</symbol>
<m:GetLastTradePrice
xmlns:m="http://wombat.ztrade.com">
....
</m:GetLastTradePrice>

26 27
03/09/2004

Sending a Message & Receiving


Getting a SOAPConnection Object
a response
SOAPConnectionFactory soapConnectionFactory = // Create an endpint point which is either URL or String type
SOAPConnectionFactory.newInstance(); java.net.URL endpoint = new URL(
SOAPConnection connection = "http://wombat.ztrade.com/quotes");
soapConnectionFactory.createConnection();
// Send a SOAPMessage (request) and then wait for
// SOAPMessage (response)
SOAPMessage response = connection.call(message, endpoint);

28 29

Reading a response
SOAPBody soapBody = response.getSOAPBody();
java.util.Iterator iterator =
soapBody.getChildElements(bodyName);
SOAPBodyElement bodyElement =
(SOAPBodyElement)iterator.next();
String lastPrice = bodyElement.getValue(); Steps of SAAJ
System.out.print("The last price for SUNW is "); Programming
System.out.println(lastPrice);
Adding Content to
SOAPHeader
30 31
03/09/2004

Adding Contents to SOAPHeader Adding Contents to SOAPHeader


? Create SOAPHeaderElement ? XML fragment generated
– Must have an associated Name object <SOAP-ENV:Header>
? Java Code <wsi:Claim conformsTo="http://ws-i.org/profiles/basic1.0/"
xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/"/>
SOAPHeader header = message.getSOAPHeader();
Name headerName = soapFactory.createName("Claim", </SOAP-ENV:Header>
"wsi", "http://ws-i.org/schemas/conformanceClaim/");
SOAPHeaderElement headerElement =
header.addHeaderElement(headerName);
headerElement.addAttribute(soapFactory.createName(
"conformsTo"), "http://ws-i.org/profiles/basic1.0/");
32 33

Adding Contents to SOAPHeader


? Adding a Textnode to
SOAPHeaderElement
headerElement.addTextNode("order");

Steps of SAAJ
Programming
Adding Content to
SOAPBody
34 35
03/09/2004

Adding Contents to SOAPBody XML fragment


SOAPBody body = soapFactory.getSOAPBody();
Name bodyName = soapFactory.createName("PurchaseLineItems", <PO:PurchaseLineItems
"PO", "http://sonata.fruitsgalore.com"); xmlns:PO="http://www.sonata.fruitsgalore/order">
SOAPBodyElement purchaseLineItems = <Order>
body.addBodyElement(bodyName); <Product>Apple</Product>
<Price>1.56</Price>
Name childName = soapFactory.createName("Order");
SOAPElement order = </Order>
purchaseLineItems.addChildElement(childName);
<Order>
childName = soapFactory.createName("Product"); <Product>Peach</Product>
SOAPElement product = order.addChildElement(childName); <Price>1.48</Price>
product.addTextNode("Apple");
</Order>
childName = soapFactory.createName("Price"); </PO:PurchaseLineItems>
SOAPElement price = order.addChildElement(childName);
price.addTextNode("1.56"); 36 37

Adding a File to SOAPBody


static Document document;
...
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
DocumentBuilder builder =
Steps of SAAJ factory.newDocumentBuilder();
document = builder.parse( new File(args[0]) );
Programming ...
// document can be any XML document
Adding a File to SOAPBody body = message.getSOAPBody();
SOAPBodyElement docElement = body.addDocument(document);
SOAPBody
38 39
03/09/2004

Adding a File to SOAPPart Object


? Create a javax.xml.transform.Source object
– using APIs from JAXP
? The XML document must be a SOAP
message format since it is setting SOAPPart
? Three types of Source objects
Steps of SAAJ – SAXSource or DOMSource
Programming ? hold content along with the instructions for

transforming the content into an XML document


Adding a File to SOAPPart – StreamSource
? holds content as an XML document
40 41

Adding a file using DOMSource Object


DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder builder = dbFactory.newDocumentBuilder();
Document document =
builder.parse("file:///music/order/soap.xml");
Steps of SAAJ
DOMSource domSource = new DOMSource(document); Programming
// Document must be a SOAP message
Adding & Accessing
SOAPPart soapPart = message.getSOAPPart(); Attachments
soapPart.setContent(domSource); 42 43
03/09/2004

Adding Contents to Attachment


Creating an AttachmentPart (Option 1: Setting Content & ContentId)
? Create from SOAPMessage object
? Example String stringContent = "Update address for Sunny Skies " +
"Inc., to 10 Upbeat Street, Pleasant Grove, CA 95439";
AttachmentPart attachment =
message.createAttachmentPart(); attachment.setContent(stringContent, "text/plain");
attachment.setContentId("update_address");
? AttachmentPart is made of two parts
– application-specific content
message.addAttachmentPart(attachment);
– associated MIME headers
? Content-Type

? attachment.setMimeHeader("Content-Type",

"application/xml");
44 45

Adding Contents to Attachment


Possible ContentType (Option 2: Using DataHandler)
? String // Create DataHandler object
? Stream URL url =
new URL ("http://greatproducts.com/gizmos/img.jpg");
? javax.xml.transform.Source DataHandler dataHandler = new DataHandler(url);
? javax.activation.DataHandler AttachmentPart attachment =
message.createAttachmentPart(dataHandler);

// Note that there is no need to set Content Type


attachment.setContentId("attached_image");

message.addAttachmentPart(attachment);

46 47
03/09/2004

Accessing Attachments
java.util.Iterator iterator = message.getAttachments();
while (iterator.hasNext()) {
AttachmentPart attachment =
(AttachmentPart)iterator.next();
String id = attachment.getContentId();
String type = attachment.getContentType();
System.out.print("Attachment " + id +
" has content type " + type);
if (type == "text/plain") {
Steps of SAAJ
Object content = attachment.getContent();
System.out.println("Attachment " +
Programming
}
"contains:\n" + content); Adding Attributes
}
48 49

Adding an Attribute to any Retrieving a value of an


SOAPElement Attribute to any SOAPElement
? Return a value of single attribute
? Java code
String attributeValue =
Name attributeName = envelope.createName("id"); person.getAttributeValue(attributeName);
person.addAttribute(attributeName, "Person7");
? Return values for all of the attributes
? XML fragment
Iterator iterator = person.getAllAttributes();
<person id="Person7"> while (iterator.hasNext()){
... Name attributeName = (Name) iterator.next();
</person> System.out.println("Attribute name is " +
attributeName.getQualifiedName());
System.out.println("Attribute value is " +
element.getAttributeValue(attributeName));
}
50 51
03/09/2004

Removeal of an Attribute from Adding Attributes to


any SOAPElement SOAPHeaderElement
? Java code ? Header attributes
boolean successful = person.removeAttribute(attributeName);
– actor
– mustUnderstand

52 53

Retriveing All
Adding Actor Attribute
SOAPHeaderElement's
SOAPHeader header = message.getSOAPHeader();
Iterator allHeaders = SOAPFactory soapFactory = SOAPFactory.newInstance();
header.examineAllHeaderElements();
String nameSpace = "ns";
while (allHeaders.hasNext()) { String nameSpaceURI = "http://gizmos.com/NSURI";
SOAPHeaderElement headerElement =
(SOAPHeaderElement)allHeaders.next(); Name order = soapFactory.createName("orderDesk",
Name headerName = nameSpace, nameSpaceURI);
SOAPHeaderElement orderHeader =
headerElement.getElementName(); header.addHeaderElement(order);
System.out.println("\nHeader name is " + orderHeader.setActor("http://gizmos.com/orders");
headerName.getQualifiedName());
Name shipping =
System.out.println("Actor is " + soapFactory.createName("shippingDesk",
headerElement.getActor()); nameSpace, nameSpaceURI);
} SOAPHeaderElement shippingHeader =
header.addHeaderElement(shipping);
shippingHeader.setActor("http://gizmos.com/shipping");
54 55
03/09/2004

Retrieving All SOAPHeaderElements Retrieving All SOAPHeaderElements


with a particular Actor (Option 1) with a particular Actor (Option 2)
// Note that an Actor is identified by an URL // Actors are detached from the SOAPHeader object
java.util.Iterator headerElements = java.util.Iterator headerElements =
header.examineHeaderElements header.extractHeaderElements
("http://gizmos.com/orders"); ("http://gizmos.com/orders");

56 57

Creating SOAPHeaderElement with Creating SOAPHeaderElement with


mustUnderstand attribute (page 1) mustUnderstand attribute (page 2)
? Java code ? XML fragment

SOAPHeader header = message.getSOAPHeader(); <SOAP-ENV:Header>


<t:Transaction
Name name = soapFactory.createName("Transaction", "t", xmlns:t="http://gizmos.com/orders"
"http://gizmos.com/orders"); SOAP-ENV:mustUnderstand="1">
SOAPHeaderElement transaction = header.addHeaderElement 5
(name); </t:Transaction>
transaction.setMustUnderstand(true); </SOAP-ENV:Header>
transaction.addTextNode("5");

58 59
03/09/2004

SAAJ nodes are DOM nodes


? At SAAJ 1.2, the SAAJ APIs extend their
counterparts in the org.w3c.dom package
– The Node interface extends the org.w3c.dom.Node
interface.

SAAJ & DOM – The SOAPElement interface extends both the Node
interface and the org.w3c.dom.Element interface.
– The SOAPPart class implements the
org.w3c.dom.Document interface.
– The Text interface extends the org.w3c.dom.Text
interface.
60 61

SAAJ nodes are DOM nodes


? SAAJ nodes and elements implement the
DOM Node and Element interfaces, you have
several options for adding or changing
message content:
– Use only DOM APIs
– Use only SAAJ APIs SAAJ Service
– Use SAAJ APIs and then switch to using DOM APIs
– Use DOM APIs and then switch to using SAAJ APIs
(with a caveat)

62 63
03/09/2004

SAAJ Service SAAJ Distributor Service


public class PriceListServlet extends HttpServlet {
static MessageFactory fac = null;
? Provides the response part of the
static {
request-response paradigm try {
fac = MessageFactory.newInstance();
? Server code is in the form of a servlet } catch (Exception ex) {
ex.printStackTrace();
? javax.servlet.HttpServlet }
};
– Init(), doPost(): set up the response message
– OnMessage(): gives the message its content

64 65

SAAJ Distributor Service SAAJ Distributor Service


public void doPost(HttpServletRequest req, SOAPMessage reply = null;
HttpServletResponse resp) reply = onMessage(msg);
throws ServletException, IOException { if (reply != null) {
try {
// Get all the headers from the HTTP request /*
MimeHeaders headers = getHeaders(req); * Need to call saveChanges because we're
* going to use the MimeHeaders to set HTTP
// Get the body of the HTTP request * response information. These MimeHeaders
InputStream is = req.getInputStream(); * are generated as part of the save.
*/
// Now internalize the contents of the HTTP request if (reply.saveRequired()) {
// and create a SOAPMessage reply.saveChanges();
SOAPMessage msg = fac.createMessage(headers, is); }

66 67
03/09/2004

SAAJ Distributor Service SAAJ Distributor Service


public SOAPMessage onMessage(SOAPMessage msg) {
resp.setStatus(HttpServletResponse.SC_OK); SOAPMessage message = null;
putHeaders(reply.getMimeHeaders(), resp);
try {
message = fac.createMessage();
// Write out the message on the response stream
OutputStream os = resp.getOutputStream(); SOAPPart part = message.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
reply.writeTo(os); SOAPBody body = envelope.getBody();
os.flush();
} else { Name bodyName = envelope.createName("price-list",
resp.setStatus( "PriceList", "http://sonata.coffeebreak.com");
SOAPBodyElement list = body.addBodyElement(bodyName);
HttpServletResponse.SC_NO_CONTENT);
} Name coffeeN = envelope.createName("coffee");
SOAPElement coffee = list.addChildElement(coffeeN);
} catch (Exception ex) {
throw new ServletException( "SAAJ POST failed: " + Name coffeeNm1 = envelope.createName("coffee-name");
ex.getMessage()); SOAPElement coffeeName =
coffee.addChildElement(coffeeNm1);
} coffeeName.addTextNode("Arabica");
} 68 69

SAAJ Distributor Service


Name priceName3 = envelope.createName("price");
SOAPElement price3 = coffee.addChildElement(priceName3);
price3.addTextNode("6.00");

Name coffeeNm4 = envelope.createName("coffee-name");


SOAPElement coffeeName4 =
coffee.addChildElement(coffeeNm4);
coffeeName4.addTextNode("House Blend");

Name priceName4 = envelope.createName("price");


SOAPElement price4 = coffee.addChildElement(priceName4);
price4.addTextNode("5.00"); SAAJ Error Handling
message.saveChanges();

} catch(Exception e) {
e.printStackTrace();
}
return message;
}
70 71
03/09/2004

SOAPFault Object SOAPFault Object Contains


? fault code (mandatory)
? Represents SOAP Fault element in – Required in SOAPFault Object
SOAP body – VersionMismatch, MustUnderstand, Client, Server
? Parties that can generate SOAPFault ? fault string (mandatory)
– Human readable explanation of the fault
– Recipient of a message in point-to-point
messaging
? fault actor (conditional)
– Required if SOAPHeader object has one or more actor
?
Indicates missing address information in purchase
attributes
order SOAP message
– Messaging provider in messaging provider-based
? Detail object (conditional)
– Required if the fault is error related to the SOAPBody object
messaging
– If not present in Client fault, SOAPBody is assumed to be OK
?
Messaging provider cannot deliver the message due to
server failure 72 73

Example 1: SOAPFault with No Example 2: SOAPFault with


Detail object Detail object
// Create SOAPBody object // Create SOAPFault object
SOAPFault fault = body.addFault();
SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
// Set fault code and fault string
SOAPBody body = envelope.getBody(); fault.setFaultCode("Client");
fault.setFaultString("Message does not have necessary info");
// Create and fill up SOAPFault object.
// Detail object contains two DetailEntry's
// Note that Detail object is not being set here since the fault has Detail detail = fault.addDetail();
// nothing to do with SOAPBody Name entryName =
SOAPFault fault = body.addFault(); envelope.createName("order", "PO", "http://gizmos.com/orders/");
DetailEntry entry = detail.addDetailEntry(entryName);
fault.setFaultCode("Server"); entry.addTextNode("quantity element does not have a value");
fault.setFaultActor("http://gizmos.com/orders");
fault.setFaultString("Server not responding"); Name entryName2 =
envelope.createName("confirmation", "PO", "http://gizmos.com/confirm");
DetailEntry entry2 = detail.addDetailEntry(entryName2);
74 entry2.addTextNode("Incomplete address: no zip code"); 75
03/09/2004

Example 3: Retrieving Example 4: Retrieving Detail


SOAPFault Object
// Get SOAPBody object // Get Detail object
SOAPBody body = newmsg.getSOAPPart().getEnvelope().getBody(); Detail newDetail = newFault.getDetail();

// Check if SOAPFault is present in the message // Get the list of DetailEntry's


if ( body.hasFault() ) { if ( newDetail != null) {
SOAPFault newFault = body.getFault(); Iterator it = newDetail.getDetailEntries();
String code = newFault.getFaultCode(); while ( it.hasNext() ) {
String string = newFault.getFaultString(); DetailEntry entry = (DetailEntry)it.next();
String value = entry.getValue();
String actor = newFault.getFaultActor();
System.out.println(" Detail entry = " + value);
if ( actor != null ) { System.out.println(" fault actor = " + actor); }
}
} }

76 77

Passion!

78

You might also like