Describe SOAP Message Construct and create a SOAP message that contains an attachment.

[Note]

A SOAP message is an XML document that consists of a mandatory SOAP envelope, an optional SOAP header, and a mandatory SOAP body.

The namespace identifier for the elements and attributes from SOAP message is "http://www.w3.org/2003/05/soap-envelope". A SOAP message contains the following:

The grammar rules are as follows:

  1. Envelope

    • The element name is "Envelope".

    • The element MUST be present in a SOAP message.

    • One or two element information items in its [children] property in order as follows:

      1. An optional Header element information item.

      2. A mandatory Body element information item.

    SOAP 1.2 Schema for Envelope:

    
    <xs:complexType name="Envelope">
      <xs:sequence>
        <xs:element ref="tns:Header" minOccurs="0"/>
        <xs:element ref="tns:Body" minOccurs="1"/>
      </xs:sequence>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
    								
    								

    Example:

    								
    <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
      <env:Header>
        <n:alertcontrol xmlns:n="http://example.org/alertcontrol">
          <n:priority>1</n:priority>
          <n:expires>2001-06-22T14:00:00-05:00</n:expires>
        </n:alertcontrol>
      </env:Header>
      <env:Body>
        <m:alert xmlns:m="http://example.org/alert">
          <m:msg>Pick up Mary at school at 2pm</m:msg>
        </m:alert>
      </env:Body>
    </env:Envelope>
    
    								

    NOTE: SOAP 1.1 allows additional elements to follow the SOAP Body element, SOAP 1.2 DISALLOWS these.

    NOTE: According to WS-I BP 1.1:

    An ENVELOPE MUST NOT have any element children of soap:Envelope following the soap:Body element.

  2. Header

    • The element name is "Header".

    • The element MAY be present in a SOAP message. If present, the element MUST be the first immediate child element of a SOAP Envelope element.

    • The element MAY contain a set of header entries each being an immediate child element of the SOAP Header element. All immediate child elements of the SOAP Header element MUST be namespace-qualified.

      NOTE: WS-I BP 1.0 requires all immediate children of Header element be namespace qualified.

    SOAP 1.2 Schema for Header:

    
    <xs:complexType name="Header">
      <xs:annotation>
        <xs:documentation>
          Elements replacing the wildcard MUST be namespace qualified, but can be in the targetNamespace
        </xs:documentation>
      </xs:annotation>
      <xs:sequence>
        <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
    								
    								

    Example:

    								
    <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope" >
      <t:Transaction xmlns:t="http://example.org/2001/06/tx" env:mustUnderstand="1" >
        5
      </t:Transaction>
    </env:Header>
    
    								

  3. Body

    • The element name is "Body".

    • The element MUST be present in a SOAP message and MUST be an immediate child element of a SOAP Envelope element. It MUST directly follow the SOAP Header element if present. Otherwise it MUST be the first immediate child element of the SOAP Envelope element.

    • The element MAY contain a set of body entries each being an immediate child element of the SOAP Body element. Immediate child elements of the SOAP Body element SHOULD be namespace-qualified.

      SOAP defines one particular direct child of the SOAP body, the SOAP fault, which is used for reporting errors.

      NOTE: WS-I BP 1.1 requires ALL immediate children of Body element be namespace qualified:

      The children of the soap:Body element in an ENVELOPE MUST be namespace qualified.

    SOAP 1.2 Schema for Body:

    
    <xs:complexType name="Body">
      <xs:sequence>
        <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:anyAttribute namespace="##other" processContents="lax"/>
    </xs:complexType>
    									
    								

    Example:

    
    <env:Body xmlns:env="http://www.w3.org/2003/05/soap-envelope">
      <m:alert xmlns:m="http://example.org/alert">
        <m:msg>Pick up Mary at school at 2pm</m:msg>
      </m:alert>
    </env:Body>
    
    								

The SOAP Body element provides a simple mechanism for exchanging mandatory information intended for the ultimate recipient of the message. Typical uses of the Body element include marshalling RPC calls and error reporting. The Body element is encoded as an immediate child element of the SOAP Envelope XML element.

If a Header element is present then the Body element MUST immediately follow the Header element, otherwise it MUST be the first immediate child element of the Envelope element. All immediate child elements of the Body element are called body entries and each body entry is encoded as an independent element within the SOAP Body element. The encoding rules for body entries are as follows:

  1. WS-I BP 1.1: The children of the soap:Body element in an ENVELOPE MUST be namespace qualified.

    WS-I BP 1.1: An ENVELOPE MUST NOT contain soap:encodingStyle attributes on any element that is a child of soap:Body.

  2. WS-I BP 1.1: An ENVELOPE described in an rpc-literal binding MUST NOT contain soap:encodingStyle attribute on any element that is a grandchild of soap:Body.

SOAP Fault

SOAP defines one body entry, which is the Fault entry used for reporting errors. Here is SOAP 1.2 Schema definition of Fault element:


<xs:complexType name="Fault" final="extension">
  <xs:annotation>
    <xs:documentation>
      Fault reporting structure
    </xs:documentation>
  </xs:annotation>
  
  <xs:sequence>
    <xs:element name="Code" type="tns:faultcode"/>
    <xs:element name="Reason" type="tns:faultreason"/>
    <xs:element name="Node" type="xs:anyURI" minOccurs="0"/>
    <xs:element name="Role" type="xs:anyURI" minOccurs="0"/>
    <xs:element name="Detail" type="tns:detail" minOccurs="0"/>
  </xs:sequence>
  
</xs:complexType>

					

Sample SOAP 1.2 fault is shown below:


<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:flt="http://example.org/faults">
  <env:Body>
    <env:Fault>
      <env:Code>
        <env:Value>env:Receiver</env:Value>
        <env:Subcode>
          <env:Value>flt:BadValue</env:Value>
        </env:Subcode>
      </env:Code>
      <env:Reason>
        <env:Text>A Fault occurred</env:Text>
      </env:Reason>
      <env:Detail>
        <flt:MyDetails>
          <flt:Message>Something went wrong at the Receiver</flt:Message>
          <flt:ErrorCode>1234</flt:ErrorCode>
        </flt:MyDetails>
      </env:Detail>
    </env:Fault>
  </env:Body>
</env:Envelope>

					

The SOAP Fault element is used to carry error and/or status information within a SOAP message. If present, the SOAP Fault element MUST appear as a body entry and MUST NOT appear more than once within a Body element. The SOAP Fault element defines two or more child element information items in its [children] property in order as follows:

  1. A MANDATORY Code element.

    
    <xs:element name="Code" type="tns:faultcode"/>
    ...
    <xs:complexType name="faultcode">
      <xs:sequence>
        <xs:element name="Value" type="tns:faultcodeEnum"/>
        <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
    
    								
    								

    The Code element information item has:

    • A [local name] of Code.

    • One or two child element information items in its [children] property, in order, as follows:

      1. A MANDATORY Value element information item.

        The type of the Value element information item is env:faultCodeEnum. SOAP 1.2 defines a small set of SOAP fault codes covering high level SOAP faults:

        
        <xs:element name="Value" type="tns:faultcodeEnum"/>
        ...
        <xs:simpleType name="faultcodeEnum">
          <xs:restriction base="xs:QName">
            <xs:enumeration value="tns:DataEncodingUnknown"/>
            <xs:enumeration value="tns:MustUnderstand"/>
            <xs:enumeration value="tns:Receiver"/>
            <xs:enumeration value="tns:Sender"/>
            <xs:enumeration value="tns:VersionMismatch"/>
          </xs:restriction>
        </xs:simpleType>
        														
        														

      2. An OPTIONAL Subcode element information item.

        
        <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/>
        ...
        <xs:complexType name="subcode">
          <xs:sequence>
            <xs:element name="Value" type="xs:QName"/>
            <xs:element name="Subcode" type="tns:subcode" minOccurs="0"/>
          </xs:sequence>
        </xs:complexType>
        														
        														

        The Subcode element information item has:

        • A [local name] of Subcode.

        • One or two child element information items in its [children] property, in order, as follows:

          1. A MANDATORY Value element information item.

            The type of the Value element information item is xs:QName. The value of this element is an application defined subcategory of the value of the Value child element information item of the Subcode element information item's parent element information item.

          2. An optional Subcode element information item.

  2. A MANDATORY Reason element information item.

    The Reason element information item is intended to provide a human-readable explanation of the fault.

    
    <xs:element name="Reason" type="tns:faultreason"/>
    ...
    <xs:complexType name="faultreason">
      <xs:sequence>
        <xs:element name="Text" type="tns:reasontext" minOccurs="1" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
    								
    								

    The Reason element information item has:

    • A [local name] of Reason.

    • One or more Text element information item children.

      Each child Text element information item MUST have a mandatory attribute information item with a [local name] of lang and [namespace name] of "http://www.w3.org/XML/1998/namespace". Note that the definition in of the lang attribute information item requires that the [prefix] is "xml" or any capitalization thereof.

      Each child Text element information item SHOULD have a different value for its xml:lang attribute information item.

      
      <xs:element name="Text" type="tns:reasontext" minOccurs="1" maxOccurs="unbounded"/>
      ...
      <xs:complexType name="reasontext">
        <xs:simpleContent>
          <xs:extension base="xs:string">
            <xs:attribute ref="xml:lang" use="required"/>
          </xs:extension>
        </xs:simpleContent>
      </xs:complexType>
      
      											
      											

  3. An OPTIONAL Node element information item.

    The Node element information item is intended to provide information about which SOAP node on the SOAP message path caused the fault to happen.

    The type of the Node element information item is xs:anyURI.

    
    <xs:element name="Node" type="xs:anyURI" minOccurs="0"/>
    								
    								

    Each SOAP node is identified by a URI. The value of the Node element information item is the URI that identifies the SOAP node that generated the fault. SOAP nodes that do not act as the ultimate SOAP receiver MUST include this element information item. An ultimate SOAP receiver MAY include this element information item to indicate explicitly that it generated the fault.

  4. An OPTIONAL Role element information item.

    The Role element information item identifies the role the node was operating in at the point the fault occurred.

    The type of the Role element information item is xs:anyURI.

    
    <xs:element name="Role" type="xs:anyURI" minOccurs="0"/>
    
    								

    The value of the Role element information item MUST be one of the roles assumed by the node during processing of the message.

  5. An OPTIONAL Detail element information item.

    The Detail element information item is intended for carrying application specific error information.

    
    <xs:element name="Detail" type="tns:detail" minOccurs="0"/>
    ...    
    <xs:complexType name="detail">
      <xs:sequence>
        <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:anyAttribute namespace="##other" processContents="lax"/> 
    </xs:complexType>
    
    								
    								

    The Detail element information item MAY have any number of character information item children. The character code of each such character information item MUST be amongst the white space characters as defined by XML 1.0. These are considered significant.

    The Detail element information item MAY be present in a SOAP fault in which case it carries additional information relative to the SOAP fault codes describing the fault. For example, the Detail element information item might contain information about a message not containing the proper credentials, a timeout, etc. The presence of the Detail element information item has no significance as to which parts of the faulty SOAP message were processed.

SOAP 1.1 allows extension of fault codes using a "dot" notation, SOAP 1.2 disallows this and provides a more XML-like representation instead.

SOAP 1.1 fault:


<e:Fault>
  <faultcode>e:Server.Memory</faultcode>
  <faultstring>Out of memory</faultstring>
</e:Fault>
					
					

SOAP 1.2 fault:


<e:Fault>
  <e:Code>
    <e:Value>e:Receiver</e:Value>
    <e:Subcode>
      <e:Value>p:Memory</e:Value>
    </e:Subcode>
  </e:Code>
  <e:Reason>Out of memory</e:Reason>
</e:Fault>

					

SOAP Fault Codes

SOAP fault codes are XML expanded names, and are intended to provide a means by which faults are classified. A hierarchical list of SOAP codes and associated supporting information is included in every SOAP fault message, with each such code identifying the fault category at an increasing level of detail.

The values of the Value child element information item of the Code element information item are RESTRICTED to those defined by the env:faultCodeEnum type (see the table below). Additional fault subcodes MAY be created for use by applications or features. Such subcodes are carried in the Value child element information item of the Subcode element information item.

SOAP fault codes are to be interpreted as modifiers of the contents of the Detail element information item in the sense that they provide the context for the Detail element information item. A SOAP node MUST understand all SOAP fault codes in a SOAP fault message in order to be able to interpret the Detail element information item in a SOAP fault.

Sample SOAP fault where the Detail element information item is to be interpreted in the context of the "env:Sender" and "m:MessageTimeout" fault codes:


<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"
              xmlns:m="http://www.example.org/timeouts"
              xmlns:xml="http://www.w3.org/XML/1998/namespace">
  <env:Body>
    <env:Fault>
      <env:Code>
        <env:Value>env:Sender</env:Value>
        <env:Subcode>
          <env:Value>m:MessageTimeout</env:Value>
        </env:Subcode>
      </env:Code>
      <env:Reason>
        <env:Text xml:lang="en">Sender Timeout</env:Text>
      </env:Reason>
      <env:Detail>
        <m:MaxTime>P5M</m:MaxTime>
      </env:Detail>    
    </env:Fault>
  </env:Body>
</env:Envelope>
					
					

NOTE: WS-I BP 1.1 PROHIBITS the use of "dot" notation of fault code (e.g. Server.Memory, or Sender.Memory).

The set of predefined fault code values is:

Table 2.4. SOAP Fault Codes

Local NameMeaning
VersionMismatch The faulting node found an invalid element information item instead of the expected Envelope element information item. The namespace, local name or both did not match the Envelope element information item required by this recommendation.
MustUnderstand An immediate child element information item of the SOAP Header element information item targeted at the faulting node that was not understood by the faulting node contained a SOAP mustUnderstand attribute information item with a value of "1".
DataEncodingUnknown

A SOAP header block or SOAP body child element information item targeted at the faulting SOAP node is scoped with a data encoding that the faulting node does not support.

DataEncodingUnknown generated when a received message uses an unrecognised value of the encodingStyle attribute.

Sender

The message was incorrectly formed or did not contain the appropriate information in order to succeed. For example, the message could lack the proper authentication or payment information. It is generally an indication that the message is not to be resent without change.

NOTE: The SOAP 1.1 "Client" fault code is renamed "Sender" in SOAP 1.2.

Receiver

The message could not be processed for reasons attributable to the processing of the message rather than to the contents of the message itself. For example, processing could include communicating with an upstream SOAP node, which did not respond. The message could succeed if resent at a later point in time.

NOTE: The SOAP 1.1 "Server" fault code is renamed "Receiver" in SOAP 1.2.

Create a SOAP message that contains an attachment.

The SOAP with Attachments API for Java (SAAJ) provides a standard way to send XML documents over the Internet from the Java platform. It is based on the SOAP 1.1 and SOAP with Attachments specifications, which define a basic framework for exchanging XML messages.

The process of creation and sending SOAP message includes following steps:

A SAAJ client is a standalone client. That is, it sends point-to-point messages directly to a Web Service that is implemented for request-response messaging. Request-response messaging is synchronous, meaning that a request is sent and its response is received in the same operation. A request-response message is sent over a SOAPConnection object via the method SOAPConnection.call, which sends the message and blocks until it receives a response. A standalone client can operate only in a client role, that is, it can only send requests and receive their responses.

A SOAPMessage object represents an XML document that is a SOAP message. A SOAPMessage object always has a required SOAP part, and it may also have one or more attachment parts. The SOAP part must always have a SOAPEnvelope object, which must in turn always contain a SOAPBody object. The SOAPEnvelope object may also contain a SOAPHeader object, to which one or more headers can be added.

The SOAPBody object can hold XML fragments as the content of the message being sent. If you want to send content that is not in XML format or that is an entire XML document, your message will need to contain an attachment part in addition to the SOAP part. There is no limitation on the content in the attachment part, so it can include images or any other kind of content, including XML fragments and documents. Common types of attachment include sound, picture, and movie data: .mp3, .jpg, and .mpg files.

The first thing a SAAJ client needs to do is get a connection in the form of a SOAPConnection object. A SOAPConnection object is a point-to-point connection that goes directly from the sender to the recipient. The connection is created by a SOAPConnectionFactory object. A client obtains the default implementation for SOAPConnectionFactory by calling the following line of code:

SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance(); 
					
The client can use factory to create a SOAPConnection object.
SOAPConnection connection = factory.createConnection();
					

Messages, like connections, are created by a factory. To obtain a MessageFactory object, you get an instance of the default implementation for the MessageFactory class. This instance can then be used to create a SOAPMessage object:

MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
					
All of the SOAPMessage objects that messageFactory creates, including message in the previous line of code, will be SOAP messages. This means that they will have no pre-defined headers. The new SOAPMessage object message automatically contains the required elements SOAPPart, SOAPEnvelope, and SOAPBody, plus the optional element SOAPHeader (which is included for convenience). The SOAPHeader and SOAPBody objects are initially empty, and the code below will illustrate some of the typical ways to add content. Content can be added to the SOAPPart object, to one or more AttachmentPart objects, or to both parts of a message.

package javax.xml.soap;

public abstract class SOAPPart implements org.w3c.dom.Document {
    public abstract SOAPEnvelope getEnvelope() throws SOAPException;				
    ...
}    
					

As stated earlier, all messages have a SOAPPart object, which has a SOAPEnvelope object containing a SOAPHeader object and a SOAPBody object.

package javax.xml.soap;

public interface SOAPEnvelope extends SOAPElement {
    public abstract Name createName(String localName, String prefix, String uri)
        throws SOAPException;
    public abstract Name createName(String localName) throws SOAPException;
    public abstract SOAPHeader getHeader() throws SOAPException;
    public abstract SOAPHeader addHeader() throws SOAPException;
    public abstract SOAPBody getBody() throws SOAPException;
    public abstract SOAPBody addBody() throws SOAPException;
}					
					

One way to add content to the SOAP part of a message is to create a SOAPHeaderElement object or a SOAPBodyElement object and add an XML fragment that you build with the method SOAPElement.addTextNode. The first three lines of the following code fragment access the SOAPBody object body, which is used to create a new SOAPBodyElement object and add it to body. The argument passed to the createName method is a Name object identifying the SOAPBodyElement being added. The last line adds the XML string passed to the method addTextNode:

SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPBody body = envelope.getBody();
Name bodyName = envelope.createName("text", "i", 
                    "http://hotitems.com");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
bodyElement.addTextNode("some-xml-text"); 
					

The content that you have just added to your SOAPBody object will look like the following when it is sent over the wire:

					
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <i:text xmlns:i="http://hotitems.com">
      some-xml-text
    </i:text>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

					

SAAJ Class Hierarchy

Another way is to add content to the SOAPPart object by passing it a javax.xml.transform.Source object, which may be a SAXSource, DOMSource, or StreamSource object. The Source object contains content for the SOAP part of the message and also the information needed for it to act as source input. A StreamSource object will contain the content as an XML document; the SAXSource or DOMSource object will contain content and instructions for transforming it into an XML document.

The following code fragments illustrates adding content as a DOMSource object. The first step is to get the SOAPPart object from the SOAPMessage object. Next the code uses methods from the JAXP API to build the XML document to be added. It uses a DocumentBuilderFactory object to get a DocumentBuilder object. Then it parses the given file to produce the document that will be used to initialize a new DOMSource object. Finally, the code passes the DOMSource object domSource to the method SOAPPart.setContent:

SOAPPart soapPart = message.getSOAPPart();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbFactory.newDocumentBuilder();
Document document = builder.parse("file:///foo.bar/soap.xml");
DOMSource domSource = new DOMSource(document);
soapPart.setContent(domSource);
					
This code would work equally well with a SAXSource or a StreamSource object.

You use the setContent method when you want to send an existing SOAP message. If you have an XML document that you want to send as the content of a SOAP message, you use the addDocument method on the body of the message:

SOAPBodyElement docElement = body.addDocument(document); 
					
This allows you to keep your application data in a document that is separate from the SOAP envelope unless and until it is time to send that data as a message.

A SOAPMessage object may have no attachment parts, but if it is to contain anything that is not in XML format, that content must be contained in an attachment part. There may be any number of attachment parts, and they may contain anything from plain text to image files. In the following code fragment, the content is an image in a JPEG file, whose URL is used to initialize the javax.activation.DataHandler object handler. The Message object message creates the AttachmentPart object attachPart, which is initialized with the data handler containing the URL for the image. Finally, the message adds attachPart to itself:

URL url = new URL("http://foo.bar/img.jpg");
DataHandler handler = new DataHandler(url);
AttachmentPart attachPart = message.createAttachmentPart(handler);
message.addAttachmentPart(attachPart); 
					

A SOAPMessage object can also give content to an AttachmentPart object by passing an Object and its content type to the method createAttachmentPart:

AttachmentPart attachPart = message.createAttachmentPart(
    "content-string", "text/plain");
message.addAttachmentPart(attachPart); 					
					

Once you have populated a SOAPMessage object, you are ready to send it. A client uses the SOAPConnection method call to send a message. This method sends the message and then blocks until it gets back a response. The arguments to the method call are the message being sent and a URL object that contains the URL specifying the endpoint of the receiver.

SOAPMessage response = soapConnection.call(message, endpoint);
					

The following example shows a SOAP 1.1 message with an attached facsimile image of the signed claim form (claim.tiff), also it illustrates the use of the cid reference in the body of the SOAP 1.1 message:


MIME-Version: 1.0
Content-Type: Multipart/Related; boundary=MIME_boundary; type=text/xml;
        start="<claim.xml@claiming-it.com>"
Content-Description: This is the optional message description.

--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <claim.xml@claiming-it.com>

<?xml version='1.0' ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    ..
    <theSignedForm href="cid:claim.tiff@claiming-it.com"/>
    ..
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

--MIME_boundary
Content-Type: image/tiff
Content-Transfer-Encoding: binary
Content-ID: <claim.tiff@claiming-it.com>

d3d3Lm1hcmNoYWwuY29taesgfSEVFES45345sdvgfszd==
--MIME_boundary--

					
NOTE: In this example the "Content-Type" header line has been continued across two lines so the example prints easily. SOAP message senders should send headers on a single long line.

NOTE: Associate the attachment to theSignedForm element by adding an href attribute. The attachment is referred to through a cid (Content-ID) URL:

					
...
<myElement href="cid:xxxx" />
...
--MIME_boundary
Content-Type: image/tiff
Content-Transfer-Encoding: binary
Content-ID: <xxxx>
...
					
					
NOTE: Unlike SOAP 1.1 XML references, do not use '#' (pound sign) in href attribute value when you refer to attachment, also when you refer to attachment you must prepend unique identifier with prefix 'cid:'.

The following listing illustrates the creation of the SOAP request. The request asks a server to resize an image. The procedure is as follows:

  1. Create SOAP connection and SOAP message objects through factories.

  2. Retrieve the message body from the message object (intermediary steps: retrieve the SOAP part and envelope).

  3. Create a new XML element to represent the request.

  4. Create the attachment and initialize it with a DataHandler object.

  5. Create more elements to represent the two parameters (source and percent).

  6. Associate the attachment to the first parameter by adding an href attribute. The attachment is referred to through a cid (Content-ID) URI.

  7. Set the value of the second parameter directly as text and call the service.

The service replies with the resized image, again as an attachment. To retrieve it, you can test for a SOAP fault (which indicates an error). If there are no faults, retrieve the attachment as a file and process it. Using SAAJ API:

// Using SAAJ
					
public File resize(String endPoint,File file) {
   SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
   SOAPMessage message = MessageFactory.newInstance().createMessage();
   SOAPPart part = message.getSOAPPart();
   SOAPEnvelope envelope = part.getEnvelope();
   SOAPBody body = envelope.getBody();
   SOAPBodyElement operation = body.addBodyElement(
       envelope.createName("resize", "ps", "http://example.com"));
   DataHandler dh = new DataHandler(new FileDataSource(file));
   AttachmentPart attachment = message.createAttachmentPart(dh);
   SOAPElement source  = operation.addChildElement("source",""),
   SOAPElement percent = operation.addChildElement("percent","");
   message.addAttachmentPart(attachment);
   source.addAttribute(envelope.createName("href"), "cid:" + attachment.getContentId());
   percent.addTextNode("20");

   SOAPMessage result = connection.call(message,endPoint);
   part = result.getSOAPPart();
   envelope = part.getEnvelope();
   body = envelope.getBody();
   if(!body.hasFault())  {
      Iterator iterator = result.getAttachments();
      if(iterator.hasNext()) {
         dh = ((AttachmentPart)iterator.next()).getDataHandler();
         String fname = dh.getName();
         if (null != fname) return new File(fname);
      }
   }
   return null;
}
					

The code above will produce following SOAP 1.1 message with attachment:


POST /ws/resize HTTP/1.0
Content-Type: multipart/related; type="text/xml"; 
     start="<EB6FC7EDE9EF4E510F641C481A9FF1F3>"; 
     boundary="----=_Part_0_7145370.1075485514903"
Accept: application/soap+xml, multipart/related, text/*
Host: example.com:8080
SOAPAction: ""
Content-Length: 1506005

------=_Part_0_7145370.1075485514903
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <EB6FC7EDE9EF4E510F641C481A9FF1F3>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <ps:resize  xmlns:ps="http://example.com">
      <source href="cid:E1A97E9D40359F85CA19D1B8A7C52AA3"/>
      <percent>20</percent>
    </ps:resize>
  </soapenv:Body>
</soapenv:Envelope>

------=_Part_0_7145370.1075485514903
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
Content-Id: <E1A97E9D40359F85CA19D1B8A7C52AA3>

d3d3Lm1hcmNoYWwuY29taesgfSEVFES45345sdvgfszd==
------=_Part_0_7145370.1075485514903--
					
					

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCDJWS 1.4 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     SCDJWS 5.0 Quiz