Skip Headers
Oracle® Application Server Advanced Web Services Developer's Guide
10g (10.1.3.1.0)

Part Number B28975-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

2 Working with Message Attachments

This chapter has the following sections.

Working with MIME Attachments

This section contains the following subsections.

How OracleAS Web Services Supports MIME Attachments

Oracle Application Server Web Services enables you to pass Multipurpose Internet Mail Extension (MIME) attachments with SOAP messages. The SOAP with Attachments (SWA) specification defines these messages.

In addition to the SOAP with Attachments specification, OracleAS Web Services also supports the Web Service-Interoperability (WS-I) Attachments Profile 1.0 that defines interoperable SOAP messages with attachments. In the interests of interoperability, the WS-I Attachments Profile adds certain constraints to the SWA specification. The profile also defines a new schema type, swaRef, for referencing MIME parts from within the SOAP message body. Using this schema type for sending interoperable SOAP messages with attachments is not mandated, nor does it guarantee conformance to the profile. The type is only an optional convenience mechanism. OracleAS Web Services support both the swaRef type and plain SWA for sending SOAP messages with MIME attachments.

OracleAS Web Services supports both the SWA and swaRef formats and their handling is transparent to the developer.

See Also:

The following list describes the main differences between swaRef and SWA.

  • swaRef attachments are uniquely identified MIME attachments, referenced in the SOAP body by a URL. SWA attachments are uniquely identified, but there is no standard way for referencing them from within a SOAP body.

  • SWA MIME parts must be defined by a mime:content element in the corresponding mime:part. The following example illustrates a ClaimPhoto JPEG file, referenced as a SWA in a mime:content element.

    <mime:part>
         <mime:content part="ClaimPhoto" 
             type="image/jpeg"/>
    </mime:part>
    

    In contrast, swaRef attachments should not be defined in the mime:content element. Instead, they should be referenced in the soapbind:body of the wsdl:binding. The following example illustrates the ClaimDetail file referenced as a swaRef in the soapbind:body element. Note that the file is referenced by a URL.

    <mime:part>
       <soapbind:body use="literal" parts="ClaimDetail"
                 namespace="http://example.com/mimetypes"/>
    </mime:part>
    
  • SWA attachments are mapped to a corresponding Java type based on the MIME content type defined in the WSDL. For example, if the MIME content type is image/jpeg, a java.awt.Image will be used to represent the attachment. In contrast, swaRef will always be mapped to javax.xml.soap.AttachmentPart.

How to Assemble a Web Service Using swaRef MIME Attachments

The swaRef type allows MIME attachments to be referenced by a URL within the SOAP body. WS-I publishes a public schema which defines the swaRef type. The public schema is defined by the following XSD:

http://ws-i.org/profiles/basic/1.1/xsd/

For more information on how to use this type to define attachments in a WSDL, see Section 4.4 of the WS-I Attachments Profile 1.0.

Note:

Only RPC-literal and document-literal Web services are supported by the WS-I Attachments Profile 1.0. Thus, only those types of services can use swaRef.

OracleAS Web Services enables you to assemble Web services up that can pass MIME attachments with swaRef. This is described in the following sections.

Steps for Assembling a Web Service Top Down

You can use WebServicesAssembler to assemble a Web service top down that can process and generate swaRef MIME attachments. One of the ways in which you could do this is to provide a WSDL that contains swaRef references as input to the genInterface command. This command generates a service endpoint interface containing methods with parameters that will be passed as attachments.

Implementing the generated service endpoint interface includes working with classes and methods in the oracle.webservices.attachments package.

See Also:

"Understanding the Streaming Attachments API" for a description of this API.

The following general steps describe how to assemble a Web service top down that exposes methods that pass swaRef MIME attachments.

  1. Provide a WSDL from which you want to assemble a Web service.

  2. Enter the import statement for the swaRef XSD in the WSDL. The following is an example import statement.

    <xsd:import namespace="http://ws-i.org/profiles/basic/1.1/xsd"
       schemaLocation="http://ws-i.org/profiles/basic/1.1/xsd"/>
    
  3. For each part in the wsdl:message that needs to be a swaRef attachment, set the type attribute to the swaRef complex type in the imported schema. An example of setting swaRef to a complex type is type="wsi:swaRef".

    "Requirements for WSDLs with swaRef Attachments" provides an example of a WSDL that references a swaRef attachment.

    Note:

    For document-literal services you should define an element in the schema with the type wsi:swaRef and reference that element in the wsdl:message part. This is because the Basic Profile requires document-literal message parts to reference elements, not types.

    In the following example, the wsdl:part name="status" in the message part references the xsd:element name="Status" of type swaRef in the schema section of the WSDL.

    <!--This is defined in the schema section of the WSDL-->
    <xsd:element name="Status" type="wsi:swaRef" />
    
    <!--This is the message part that references the swaRef element-->
    <wsdl:message name="replacePhotoResponse">
        <wsdl:part name="status" type="types:Status"/>
      </wsdl:message>
    
  4. Use the WSDL as input to the WebServicesAssembler genInterface command. Following is a sample genInterface command.

    java -jar wsa.jar genInterface -wsdl mySwaRefWsdl -output c:\appDir
    

    This command generates a service endpoint interface with methods that handle swaRef attachments and a Java class for each complexType in the WSDL. The AttachmentPart class will be used for all instances of swaRef.

    "How to Implement a Service Endpoint Interface with Attachments" provides a sample generated service endpoint interface.

  5. Implement the generated service endpoint interface.

    In the implementation class, methods that receive attachments will have an AttachmentPart parameter while methods that send swaRef attachments will have AttachmentPart as the return type. As part of the implementation of the methods, create a new instance of the AttachmentPart and add an attachment using the setContent method.

    See Also:

Requirements for WSDLs with swaRef Attachments

A WSDL that uses swaRef attachments must have the following characteristics.

  • The WSDL must import the swaRef XSD file.

  • Each part of the wsdl:message that must be a swaRef attachment must set its type attribute to the swaRef complex type in the imported schema (or the element attribute set to an element that is of type swaRef for document-literal services).

  • The swaRef attachment should be referenced in the soapbind:body of the wsdl:binding. Example 2-1 illustrates the format of the swaRef reference. The soapbind:body element has these attributes:

    • use—indicates whether the message format is literal or encoded.

    • parts—indicates the part of the SOAP message that the attachment references.

    • namespace—indicates the URL of the attachment.

    Example 2-1 swaRef Attachment Referenced in the soapbind:body Element

    <mime:part>
       <soapbind:body use="literal|encoded" parts="string" namespace="URL"/>
    </mime:part>
    

Example 2-2 illustrates a WSDL that contains a swaRef reference that can be used as input to genInterface. The ClaimDetailType complex type which is referenced by the ClaimDetail part of the ClaimIn message has an element ClaimForm that is of type swaRef. The ClaimDetail part is referenced in the soapbind:body of the binding as opposed to a mime:content element which is not referenced as part of the SOAP body. The elements described in the preceding list, as well as the xsd:import statement for the swaRef schema, are highlighted in bold.

Example 2-2 WSDL that References a swaRef Attachment

<?xml version="1.0"?>
<wsdl:definitions xmlns:types="http://example.com/mimetypes"
    xmlns:ref="http://ws-i.org/profiles/basic/1.1/xsd" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soapbind="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
    targetNamespace="http://example.com/mimewsdl" 
xmlns:tns="http://example.com/mimewsdl">
    <wsdl:types>
        <xsd:schema targetNamespace="http://example.com/mimetypes" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <xsd:import namespace="http://ws-i.org/profiles/basic/1.1/xsd"  
                        schemaLocation="http://ws-i.org/profiles/basic/1.1/xsd"/>
            <xsd:complexType name="ClaimDetailType">
                <xsd:sequence>
                    <xsd:element name="Name" type="xsd:string"/>
                    <xsd:element name="ClaimForm" type="ref:swaRef"/>
                </xsd:sequence>
            </xsd:complexType>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="ClaimIn">
        <wsdl:part name="ClaimDetail" type="types:ClaimDetailType"/>
    </wsdl:message>
    <wsdl:message name="ClaimOut">
        <wsdl:part name="ClaimRefNo" type="ref:swaRef"/>
    </wsdl:message>
    <wsdl:portType name="ClaimPortType">
        <wsdl:operation name="SendClaim">
            <wsdl:input message="tns:ClaimIn"/>
            <wsdl:output message="tns:ClaimOut"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="ClaimBinding" type="tns:ClaimPortType">
        <soapbind:binding style="rpc" 
transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="SendClaim">
            <soapbind:operation soapAction="http://example.com/soapaction"/>
            <wsdl:input>
                <mime:multipartRelated>
                    <mime:part>
                        <soapbind:body use="literal" 
                                       parts="ClaimDetail" 
                                       namespace="http://example.com/mimetypes"/>
                    </mime:part>                  
                </mime:multipartRelated>
            </wsdl:input>
            <wsdl:output>
                <mime:multipartRelated>
                    <mime:part>
                        <soapbind:body use="literal" 
namespace="http://example.com/mimetypes"/>
                    </mime:part>
                </mime:multipartRelated>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
</wsdl:definitions>

From this WSDL, the genInterface command generates a service endpoint interface with swaRef attachments, and a Java class for each complexType in the WSDL. The AttachmentPart class will be used for all instances of swaRef.

For example, WebServicesAssembler will generate a Java class for the ClaimDetail complex type. Its claimForm parameter, which is of type swaRef in the WSDL, will be generated as type AttachmentPart in the Java code. The following code sample illustrates part of the class signature.

public class ClaimDetail{
   private String name;
   private javax.xml.soap.AttachmentPart claimForm;
   ...
}
How to Implement a Service Endpoint Interface with Attachments

Given a WSDL with references to swaRef attachments, WebServicesAssembler generates a service endpoint interface that contains a Java class for each complexType in the WSDL. It also contains Java methods that return a java.xml.soap.AttachmentPart for each WSDL operation that has a swaRef in the output method.

An implementation of a generated service endpoint interface must create a new instance of AttachmentPart. OracleAS Web Services uses the AttachmentPart class for creating and accessing swaRef attachments. Since AttachmentPart is an abstract class, it cannot be instantiated directly. You must create a new instance of AttachmentPart as a part of the implementation of methods that send attachments.

See Also:

"How to Create a New Instance of AttachmentPart" for information on how to use the SAAJ API to create a new instance of AttachmentPart.

Example 2-3 illustrates a generated service endpoint interface with a sendClaim method that sends an attachment as a return parameter. Example 2-4 illustrates the implementation of the interface.

Example 2-3 Sample Generated Service Endpoint Interface with an Attachment

package com.demo.attachments;

import java.xml.soap.AttachmentPart;
...
public interface claimPortType extends java.rmi.Remote{
   public AttachmentPart sendClaim(ClaimDetail claimDetail) throws
     java.rmi.RemoteException;
}

The implementation class in Example 2-4 creates a new instance of AttachmentPart in the sendClaim method. Once the AttachmentPart instance is created, an image or any other object can be added using the setContent(Object obj, String mimeType) method. The first parameter of the method takes the object to be attached and the second parameter specifies the MIME content type of that object. For example, if a GIF image is being sent, the setContent method would be setContent(newPhoto,"image/gif").

Example 2-4 Implementation of a Service Endpoint Interface

public class ClaimPortTypeImpl implements ClaimPortType {

   public AttachmentPart sendClaim(ClaimDetail claimDetail) throws RemoteException{
   AttachmentPart impl = null;
   try{
   MessageFactory factory = MessageFactory.newInstance();
   SOAPMessage  message = factory.createMessage();
   impl = message.createAttachmentPart();
} catch(SOAPException ex){
   return null;
}
return impl;
}
How to Create a New Instance of AttachmentPart

This section illustrates the basic code for creating a new instance of AttachmentPart. OracleAS Web Services uses the AttachmentPart class for creating and accessing swaRef attachments.

Example 2-5 illustrates sample code that uses the SAAJ API to create a new instance of AttachmentPart. Note that the createAttachmentPart method of javax.xml.soap.SOAPMessage takes an object and a MIME type as parameters.

Example 2-5 Creating a New Instance of AttachmentPart

javax.xml.soap.MessageFactory mf = javax.xml.soap.MessageFactory.newInstance();
javax.xml.soap.SOAPMessage message = mf.createMessage();
javax.xml.soap.AttachmentPart ap = message.createAttachmentPart(attachmentObj,"image/jpeg");

The generated service interface can now be implemented and swaRef attachments can be sent and received using AttachmentPart from the SAAJ API.

Steps for Assembling a Web Service Bottom Up

You can use WebServicesAssembler to assemble a Web service bottom up that can pass swaRef MIME attachments. One way to do this is to provide a Java class that contains method parameters that represent attachments to the assemble or genWsdl commands. These commands produce a WSDL with references to swaRef attachments.

See Also:

"Understanding the Streaming Attachments API" for a description of this package.

Note:

WebServicesAssembler will not be able to assemble a Web service that can pass swaRef MIME attachments if you specify an RPC-encoded message format. To assemble the service, you must select a different format.

The following general steps describe how to assemble a Web service bottom up that exposes elements in the WSDL that represent swaRef MIME attachments.

  1. Provide the Java class you want to expose as a Web service.

    In the class file, any methods that use parameters that represent attachments should be identified as type AttachmentPart. In your implementation of the methods that use attachments, create a new instance of AttachmentPart.

    "How to Create a New Instance of AttachmentPart" provides sample code that uses the SAAJ API to do this. "How to Write a Service Endpoint Interface that Handles Attachments" provides a sample service endpoint interface with a method that passes attachments.

  2. Use the WebServicesAssembler to generate a WSDL file.

    • Use the assemble command if you want to assemble the WSDL and all of the service artifacts for a Web service.

    • Use the genWsdl command if you want to generate only the WSDL file.

    The generated WSDL file will contain the following element for each parameter in the Java class identified as type AttachmentPart.

    <xsd:element name="..." type="ref:swaRef"/>

    "How to Assemble a WSDL File with swaRef Attachment References" provides a sample WSDL file generated with the genWsdl command that contains swaRef attachment references.

  3. If you used the genWsdl command to generate the WSDL, you can now inspect the file.

  4. If you used the assemble command to assemble the Web service, you can now deploy the service, generate a proxy, and write a client.

    See Also:

    "Assembling a Web Service with Java Classes" in the Oracle Application Server Web Services Developer's Guide for more information on the steps for assembling and deploying a Web service, and generating client code.

How to Write a Service Endpoint Interface that Handles Attachments

If methods in your service endpoint interface pass attachments, and you want the attachments to be passed as a swaRef, then the parameters that represent the attachments must be of type AttachmentPart. In bottom up Web service assembly scenarios, WebServicesAssembler generates a swaRef type reference into the WSDL for every AttachmentPart type it encounters in an implementation class or interface.

Example 2-6 illustrates an interface that contains a parameter, claimDetail, of type AttachmentPart. When passed to WebServicesAssembler using the genWsdl or assemble command, this interface yields a WSDL file.

Example 2-6 Service Endpoint Interface with a Method that Passes Attachments

public interface ClaimServicePortType extends java.rmi.Remote{
   public String sendClaim(int id, AttachmentPart claimDetail) throws RemoteException;
   }
How to Assemble a WSDL File with swaRef Attachment References

Example 2-7 illustrates a fragment of the WSDL file, displaying only the type definitions. The example assumes that the interface in Example 2-6 was used as input to the genWsdl command to generate the WSDL with document-wrapped style. The WSDL fragment identifies the claimDetail element as being of type swaRef (highlighted in bold).

Note that the same WSDL fragment would be created if the assemble command was used to generate the WSDL. This is the default behavior when WebServicesAssembler encounters the AttachmentPart data type.

Example 2-7 WSDL Fragment, Displaying only Type Definitions

...
        <xsd:import namespace="http://ws-i.org/profiles/basic/1.1/xsd" />
        <xsd:complexType name="sendClaimType">
            <xsd:sequence>
                <xsd:element name="id" type="xsd:string"/>
                <xsd:element name="claimDetail" type="ref:swaRef"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:schema>
</wsdl:types>
...

How to Assemble a Web Service Using SWA MIME Attachments

This section contains the following subsections:

Understanding SWA MIME Attachments

SWA attachments refer to attachments that conform to the SOAP With Attachments (SWA) specification. Currently, WebServicesAssembler supports only top down assembly of Web services with WSDL files that contain SWA attachments. SWA MIME parts are defined in the <wsdl:binding> clause of the WSDL. The attachment is defined by a mime:content element in the corresponding mime:part.

Example 2-8 illustrates the format of the mime:content element and its part and type attributes. The part attribute identifies the part of the SOAP message to which the attachment belongs. The type attribute identifies the content type in the attachment.

Example 2-8 SWA Attachment Referenced in the mime:content Element

<mime:part>
     <mime:content part="string" 
         type="content type"/>
</mime:part>

WebServicesAssembler processes each mime:content element found in the WSDL file and maps it to a Java type that corresponds to the MIME-content type.

Table 2-1 displays the MIME content types and corresponding Java types to which they will be mapped. The default type for any MIME-content type that is not recognized is javax.activation.DataHandler.

Table 2-1 Mapping Content Types for SWA Attachments

Content Type Java Type

image/jpeg, image/gif, image/tif

java.awt.Image. If these content types are used in combination, or if image/* is specified, then they are mapped to the java.activation.DataHandler Java type.

text/plain, application/plain

java.lang.String. If these types are used in combination, then they are mapped to the java.activation.DataHandler Java type.

text/xml

java.activation.DataHandler


Steps for Assembling a Web Service with SWA Attachments Top Down

The following steps describe how to generate a service endpoint interface that can handle SWA attachments. In the steps, JPG content is used as an example of a content type that will be represented as a Java class in the interface. However, any content type described in Table 2-1 can be used.

  1. Provide the WSDL from which you want to generate a Web service.

  2. Ensure that each element that represents a SWA attachment appears in a <mime:content...> element in the <wsdl:binding...> clause of the WSDL.

    In Example 2-9, a photo JPEG attachment appears in a <mime:content...> element:

    <mime:part>
        <mime:content part="photo" 
                      type="image/jpeg"/>
    </mime:part>
    
  3. Use the WSDL as input to the WebServicesAssembler genInterface command. Following is a sample genInterface command.

    java -jar wsa.jar genInterface -wsdl mySwaWsdl -output c:\appDir
    

    The genInterface command generates a service endpoint interface with parameters that represent SWA attachments and a Java class for each complexType in the WSDL. This Java class will be used for all instances of SWA attachments.

    Example 2-10 illustrates a generated service endpoint interface with a parameter that represents a SWA attachment as a java.awt.Image Java data type.

  4. Implement the generated service endpoint interface.

Sample WSDL with SWA MIME References

Example 2-9 illustrates a WSDL that contains a SWA reference that can be used as input to genInterface. Note that this WSDL example omits the wsdl:service element for the sake of brevity.

Example 2-9 WSDL that References a SWA Attachment

<wsdl:definitions
  name="PhotoCatalogService"
  targetNamespace="http://examples.com/PhotoCatalog"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:types="http://examples.com/PhotoCatalog/types"
  xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
  xmlns:tns="http://examples.com/PhotoCatalog">
  <wsdl:message name="addPhotoRequest">
    <wsdl:part name="photo" type="xsd:hexBinary"/>
  </wsdl:message>
  <wsdl:message name="addPhotoResponse">
    <wsdl:part name="status" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="replacePhotoRequest">
    <wsdl:part name="oldPhoto" type="xsd:string"/>
    <wsdl:part name="newPhoto" type="xsd:hexBinary"/>
  </wsdl:message>
  <wsdl:message name="replacePhotoResponse">
    <wsdl:part name="status" type="xsd:string"/>
  </wsdl:message>
  <wsdl:portType name="PhotoCatalog">
    <wsdl:operation name="addPhoto">
      <wsdl:input message="tns:addPhotoRequest"/>
      <wsdl:output message="tns:addPhotoResponse"/>
    </wsdl:operation>
    <wsdl:operation name="replacePhoto">
      <wsdl:input message="tns:replacePhotoRequest"/>
      <wsdl:output message="tns:replacePhotoResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="PhotoCatalogBinding" type="tns:PhotoCatalog">
    <soap:binding style="document" 
transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="addPhoto">
      <wsdl:input>
        <mime:multipartRelated>
          <mime:part>
            <soap:body use="literal"/>
          </mime:part>
          <mime:part>
            <mime:content part="photo" 
                          type="image/jpeg"/>
          </mime:part>
        </mime:multipartRelated>
      </wsdl:input>
      <wsdl:output>
        <mime:multipartRelated>
          <mime:part>
            <soap:body use="literal"/>
          </mime:part>
          <mime:part>
            <mime:content part="status" type="text/plain"/>
            <mime:content part="status" type="text/xml"/>
          </mime:part>
        </mime:multipartRelated>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="replacePhoto">
      <wsdl:input>
        <mime:multipartRelated>
          <mime:part>
            <soap:body parts="oldPhoto" use="literal"/>
          </mime:part>
          <mime:part>
            <mime:content part="newPhoto" 
                          type="image/jpeg"/>
          </mime:part>
        </mime:multipartRelated>
      </wsdl:input>
      <wsdl:output>
            <soap:body parts="status" use="literal"/>        
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
</wsdl:definitions>

Sample Generated Interface with Parameters that Can Pass SWA Attachments

Given the WSDL displayed in Example 2-9, the WebServicesAssembler genInterface command generates the interface in Example 2-10. The photo and newPhoto parameters are generated with the Java data type java.awt.Image because their mime:content is defined with image/jpeg. An implementation of the interface can now pass JPEG files as attachments for the photo part. This is the same for RPC-literal and document-literal (wrapped and bare). The return for the addPhoto method is mapped to DataHandler because there was a mine:content binding in the WSDL for that operation.

Example 2-10 Generated Interface with a SWA Attachment

public interface PhotoCatalog extends java.rmi.Remote{
   public javax.activation.DataHandler addPhoto (java.awt.Image photo) throws java.rmi.RemoteException;

  public String replacePhoto(java.awt.Image newPhoto, String oldPhoto) throws java.rmi.RemoteException;
   }

How to Add MIME Attachments to SOAP Fault Messages

This section describes how to add MIME type attachments to SOAP fault messages. It contains the following subsections:

Note:

In OracleAS Web Services, you can add only MIME type attachments to SOAP fault messages.

Understanding SOAP Fault Messages with Attachments

In SOAP, an attachment is added to the fault message when the Web service implementation class throws an exception. The WS-I Attachments Profile 1.0 specifies that a SOAP fault can contain attachments only if a <mime:part> element appears in an operation's output message in the WSDL. Thus, if custom faults appear in a WSDL operation that has an output message with an attachment, WebServicesAssembler generates a special exception class that handles attachments in the fault.

The WSDL fragment in Example 2-11 illustrates the <mime:part> in the <wsdl:operation> clause that declares that an operation can output MIME content. The namespace attribute is required only when you are working with RPC-literal messages. The WSDL fragment also illustrates the <wsdl:fault> element that defines the fault that the operation can throw.

Example 2-11 WSDL Fragment, that Defines a SOAP Fault

<wsdl:operation>
...
<wsdl:output>
  <mime:multipartRelated>  
    <mime:part>
      <soap:body parts="string" use="literal|encoded" [namespace="URL"]/>
    </mime:part>
  </mime:multipartRelated>  
</wsdl:output>
<wsdl:fault name="string">
    <soap:fault name="string" use="literal|encoded"/>
</wsdl:fault>
</wsdl:operation>

When WebServicesAssembler encounters a <wsdl:fault> element, it generates a com.examples.types.Fault_NameType exception class (as defined in Example 2-9), where Fault_Name is the value of the name attribute in the wsdl:fault element.

An implementation of a method that throws a generated fault class must also include an implementation of a new instance of the class. It must also include code to add the attachment to the exception.

Writing and implementing the Java classes that contain attachments includes working with classes and methods in the oracle.webservices.attachments package.

See Also:

"Understanding the Streaming Attachments API" for a description of this package.

Note:

Faults with attachments can be added to a Web service only when you are assembling it from a WSDL (top down). They cannot be added when assembling a Web service bottom up.

Steps for Assembling SOAP Faults with Attachments into a Web Service Top Down

The following general steps describe how to add attachments to SOAP fault messages and generate them into the service endpoint interface.

  1. Provide the WSDL that you want to work with.

  2. Edit the WSDL operation that you want to throw a fault with attachment content.

    1. Declare the output element that will contain attachment content in the <wsdl:output.../> clause. The clause must contain <mime:multipartRelated> content.

    2. Define a <wsdl:fault.../> element.

      "How to Specify SOAP Faults with Attachments in the WSDL" provides a sample WSDL that has been edited to include the wsdl:output and wsdl:fault elements.

  3. Use the WebServicesAssembler genInterface command to generate a service endpoint interface.

    java -jar wsa.jar genInterface -wsdl myWsdl -output c:\appDir
    

    The methods in the service endpoint interface that use the attachment data will have a parameter that takes an attachment data type. The methods will throw an exception that implements oracle.webservices.attachments.AttachmentFault.

  4. Implement the interface.

    In the implementation, include code to perform the following tasks.

    1. Create a new instance of the exception that implements oracle.webservices.attachments.AttachmentFault

    2. Add an attachment to the exception with the addAttachment method.

      "How to Implement a Method that Throws Faults with Attachments" provides sample code that creates a new instance of the exception and adds the attachment to it.

  5. Compile the interface and the implementation, deploy the service, and assemble the client code.

    See Also:

    "Assembling a Web Service from a WSDL" in the Oracle Application Server Web Services Developer's Guide for more detail on the steps for assembling and deploying a Web service, and assembling client code.

How to Specify SOAP Faults with Attachments in the WSDL

To specify a SOAP fault that can throw attachment content, the WSDL operation must identify the following attributes:

  • the namespace of the attachment content

  • whether the fault's message use is literal or encoded

  • the part of the SOAP message that the fault belongs to

The WSDL fault itself must identify its name and whether its message use is literal or encoded. The <wsdl:fault> clause appears as a peer to the WSDL input and WSDL output clauses.

Example 2-12 illustrates a WSDL fragment for the replacePhoto binding operation with wsdl:output and wsdl:fault elements. Because wsdl:output identifies MIME content, the fault message defined by wsdl:fault will be able to contain attachments.

Example 2-12 WSDL Fragment, Displaying only Port Types and Binding Declarations

<wsdl:operation name="replacePhoto">
      <wsdl:input>
        <mime:multipartRelated>
          <mime:part>
            <soap:body parts="oldPhoto" use="literal" namespace="http://examples.com/PhotoCatalog"/>
          </mime:part>
          <mime:part>
            <mime:content part="newPhoto" type="image/jpeg"/>
          </mime:part>
        </mime:multipartRelated>
      </wsdl:input>
      <wsdl:output>
        <mime:multipartRelated>
          <mime:part>
            <soap:body parts="status" use="literal" namespace="http://examples.com/PhotoCatalog"/>
          </mime:part>
        </mime:multipartRelated>
      </wsdl:output>
      <wsdl:fault name="InvalidPhoto">
          <soap:fault name="InvalidPhoto" use="literal"/>
      </wsdl:fault>
    </wsdl:operation>

How to Implement a Method that Throws Faults with Attachments

A method in the generated service endpoint interface that can throw a fault with attachment content contains a parameter that takes an attachment data type and throws a exception that implements oracle.webservices.attachments.AttachmentFault. An implementation of the method must create a new instance of the exception. It must also add the attachment to the exception. The oracle.webservices.attachments package provides an FaultWithAttachments.addAttachment method to do this.

See Also:

"Understanding the Streaming Attachments API" for more information on the addAttachment method.

Example 2-13 illustrates an implementation of the replacePhoto operation defined by the WSDL fragment in Example 2-12. The InvalidPhoto fault defined in the WSDL is mapped to the com.examples.types.InvalidPhotoType exception class.

As required, the implementation of replacePhoto creates a new instance of the InvalidPhotoType exception. It also adds the attachment to the exception with the FaultWithAttachments.addAttachment method. The InvalidPhotoType can then be thrown as an exception which causes it to be transmitted as a SOAP fault with attachments.

Example 2-13 Implementing a Method that Throws Faults with Attachments

public AttachmentPart replacePhoto(PhotoInfoType oldPhoto, Image newPhoto) throws
            RemoteException,com.examples.types.InvalidPhotoType {
        if(newPhoto == null){
            return null;
        }
        if(oldPhoto.getPhotoID() == -1){
            InvalidPhotoType typeException = new InvalidPhotoType(-1,"InvalidPhotoType","The PhotoId specified is invalid");
                try{
                    Image image = javax.imageio.ImageIO.read(new File("myImage"));
                    typeException.addAttachment(image,"image/jpeg");
                }catch(Exception e){
                throw new RemoteException("unexpected exeption",e);
            }
                throw typeException;
        }
         AttachmentPart impl = null;
             try{
                MessageFactory factory = MessageFactory.newInstance();
                SOAPMessage message = factory.createMessage();
                impl = message.createAttachmentPart();
            }catch(SOAPException ex){
                return null;
          }
          return impl;
    }

How to Retrieve SOAP Faults with Attachments on the Client

A J2SE or J2EE Web service client can be coded to retrieve SOAP faults with attachments thrown by the service. The oracle.webservices.attachments package provides methods that can use retrieve attachment content from the fault. For example, the getAttachments method can be used to get an iterator of the list of attachments in the fault. The hasAttachments method can be used to query if a fault has an attachment.

Example 2-14 illustrates a client stub, photoCatalog, that can retrieve attachment content. The example assumes that the oldPhoto and newPhoto parameters have been previously defined, and the InvalidPhotoType exception implements oracle.webservices.attachments.AttachmentFault. Since InvalidPhotoType implements AttachmentFault, it is a SOAP fault that can contain attachments.

The hasAttachments method tests for attachments in the fault. If this method returns true, the SOAP fault has attachments. The getAttachments method retrieves all of the attachments in a SOAP fault. This method returns an iterator containing an AttachmentPart object for each attachment in the SOAP fault.

Example 2-14 Web Service Client with Code for Retrieving Attachments

public class MyClientExample{
 
PhotoCatalog photoCatalog = getPhotoCatalogPortType(); //create a client stub 
for the web service
try{
    //assuming oldPhoto and newPhoto are defined
    photoCatalog.replacePhoto(oldPhoto, newPhoto);

   // assuming InvalidPhotoType implements AttachmentFault
}catch(InvalidPhotoType type){
    if(type.hasAttachments()){
       java.util.Iterator it = type.getAttachments();
       AttachmentPart p = (AttachmentPart)it.next();
       //do something useful with the attachment.
    }
}

Working with Streaming Attachments

This section contains the following subsections:

Understanding Streaming Attachments

OracleAS Web Services enables you to pass large attachments as a stream. As opposed to the JAX-RPC API, which requires attachments to be materialized entirely in memory, streams make the programming model more efficient to use. Streaming attachments also enhance performance and scalability in that there is no need to load the entire attachment into memory before service execution.

Like embedded attachments, streamed attachments conform to the multipart-MIME binary format. On the wire, messages with streamed attachments are identical to any other SOAP message with attachments.

Note:

Consider using streamed attachments if the messages you are trying to pass are over one Megabyte in size. Messages over 100 Megabytes in size should definitely be passed as streamed attachments.

Example 2-15 provides a sample message with a streamed attachment. The first "part" in the message is the SOAP envelope (<SOAP-ENV:Envelope...). The second "part" is the attachment, in this case, myImage.gif.

Example 2-15 Sample Message with a Streamed Attachment

MIME-Version: 1.0
Content-Type: Multipart/Related; boundary=MIME_boundary; type=text/xml;
Content-Description: This is the optional message description.

--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: NotSure/DoesntMatter

<?xml version='1.0' ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
..
<DocumentName>MyImage.gif</DocumentName>
..
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

--MIME_boundary
Content-Type: image/gif
Content-Transfer-Encoding: binary
Content-ID: AnythingYoudLike

...binary GIF image...
--MIME_boundary--

Limitations on Streaming Attachments

There are some limitations on streamed attachments in OracleAS Web Services.

  • A Web service port can send only embedded attachments or streamed attachments; not both.

  • Handlers cannot obtain access to streamed attachments.

  • Any message with streamed attachments will appear to all handlers as a SOAP message without attachments.

See Also:

"Understanding the Streaming Attachments API" for more information on the Attachments interface.

Understanding the Streaming Attachments API

The Attachments API provides a programmatic interface to streaming attachments. Streamed attachments are directional; they can be classified as "incoming" (service requests or client responses) and "outgoing" (service responses or client requests). Incoming streams can only be read and outgoing streams can only be written to.

Streaming is enabled by adding an extra parameter to each service or stub operation that wants to stream attachments. This parameter must be of type Attachments (oracle.webservices.attachments.Attachments). The Attachments interface provides methods for reading incoming attachment streams and for adding outgoing attachment streams.

The API resides in the oracle.webservices.attachments package. Table 2-2 summarizes the interfaces and classes in the Attachments API. The sections following the table provide more detail.

Table 2-2 Interfaces in the Attachments API

Interface or Class Description

Attachment interface

The Attachment object consists of a String ID to identify the attachment and a data handler to retrieve the data. See "Interface for Attachment Objects" for more information.

AttachmentFactory class

This factory class creates instances of Attachments and Attachment objects. See "Factory Class for Attachment Objects" for more information.

Attachments interface

Root interface for managing attachments. This interface contains methods for storing attachments as either incoming or outgoing attachments. See "Interface for Attachments" for more information.

IncomingAttachments interface

Provides iterators to process incoming attachments. These can be request attachments on the server or response attachments on the client. See "Interface for Incoming Attachments" for more information.

OutgoingAttachments interface

Collects outgoing attachments for streaming after the message is serialized. These can be request attachments on the client or response attachments on the server. See "Interface for Outgoing Attachments" for more information.


Interface for Attachment Objects

The Attachment object consists of a String ID to identify the attachment and a data handler to retrieve the data. It is used by the addAttachment method in the OutgoingAttachments interface to add an attachment to the output stream.

interface Attachment {
    public String getId();
    public DataHandler getDataHandler();
}

Factory Class for Attachment Objects

The package provides a factory class for creating instances of Attachments and Attachment objects. When you are using streaming attachments in a stub, you must create the Attachments object before you call the service.

abstract class AttachmentFactory {
    public Attachments createAttachments();
    public Attachment createAttachment (String id, 
                 String contentType, InputStream attachmentStream);
    public Attachment createAttachment (String id, DataHandler handler);
    public static AttachmentFactory newInstance();
} 

Interface for Attachments

Attachments is the root interface for managing attachments. The getIncomingAttachments method returns an IncomingAttachments object. It returns null if there are no incoming attachments. The getOutgoingAttachments method always returns an OutgoingAttachments object.

public interface Attachments {
    IncomingAttachments getIncomingAttachments();
    OutgoingAttachments getOutgoingAttachments();
}

Interface for Incoming Attachments

The IncomingAttachments interface is used for request attachments on the server and for response attachments on the client. It is, essentially, an iterator over attachments. The interface includes a close method that tells the runtime to flush any remaining attachments from the stream. This must be called after all attachments have been processed so the connection can be cleared for the next request.

interface IncomingAttachments {
    public boolean hasNextAttachment() throws IOException;
    public Attachment nextAttachment() throws IOException;  
    public void close() throws IOException;
}

Interface for Outgoing Attachments

The OutgoingAttachments interface is used for request attachments on the client and for response attachments on the server. It collects attachments for streaming after the message is serialized. The interface includes an addAttachment method to add attachments to the output stream. You can create attachments using the methods described in "Factory Class for Attachment Objects".

interface OutgoingAttachments {
    public void addAttachment (Attachment attachment);
}

WSDL Extensions for Streaming Attachments

Streaming attachments use a WSDL extension, <stream-attachments>, to notify the WebServicesAssembler tool that attachment data will be streamed. The element takes a required string attribute, name, as the parameter name for the generated Java classes and interfaces. The element is specified in an Oracle namespace:

http://oracle.com/schemas/webservices/streaming-attachments

The element can be used only at the binding operation level.

Example 2-19 illustrates a WSDL that contains the <stream-attachments> element. Example 2-16 illustrates the <stream-attachments> schema.

Example 2-16 XML Schema for Streaming Attachments

<schema
    xmlns="http://www.w3.org/2000/10/XMLSchema"
    xmlns:sa="http://oracle.com/schemas/webservices/streaming-attachments" 
    targetNamespace="http://oracle.com/schemas/webservices/streaming-attachments">
  <element name="stream-attachments" type="sa:streamAttachemntsType"/>
  <complexType name="streamAttachemntsType">
    <attribute name="name" type="string" use="required"/>
  </complexType>
</schema>

How to Assemble Streaming Attachments into a Web Service

This section describes how to assemble a Web Service that uses streaming attachments.

Steps for Assembling a Web Service that Supports Streaming Attachments Bottom Up

The model for assembling a Web service bottom up that supports streaming attachments is the same as any other service based on Java classes. "Assembling a Web Service with Java Classes" in the Oracle Application Server Web Services Developer's Guide provides more information on assembling a Web service bottom up with Java classes.

  1. Write a public interface that contains the remote methods that you want to expose as a service. In this case, one or more of the methods will use the Attachment API.

    "How to Write an Interface for Steaming Attachments" provides more information on this step.

  2. Write the implementation of the service.

    "How to Implement a Service Interface that Uses Streaming Attachments" provides more information on this step.

  3. Write the stub code for the Web service client. To use a stub to send or receive attachments, you must create the Attachments object before the call.

    "How to Write Stub Code to Handle Streaming Attachments" provides more information on this step.

  4. Generate the service artifacts by running the WebServicesAssembler with the assemble command.

    "Sample Generated WSDL for a Service with Streaming Attachments" illustrates a sample generated WSDL.

  5. Deploy the service and bind the application.

  6. Generate the client-side code.

  7. Compile and run the client.

How to Write an Interface for Steaming Attachments

If you want to stream attachments as a part of your Web service, then at least one of the methods within the service interface must contain a parameter of type Attachments (oracle.webservices.attachments.Attachments). The Attachments type indicates objects will be streamed by OracleAS Web Services.

Example 2-17 illustrates the service interface for a Web service that stores large image files in a local database. The request includes an image name, a description, and the image to be stored. Note that the attachments parameter of type Attachments indicates that the image will be streamed.

Example 2-17 Service that Uses Streaming Attachments

public interface ImageStore extends java.rmi.Remote {
    public void storeImage (String name, String desc, Attachments attachments) throws java.rmi.RemoteException; 
}

If you use this interface to generate a Web service bottom up, WebServicesAssembler will detect the parameter of type Attachments. Support for streaming attachments will automatically be generated into the Web service.

See Also:

Example 2-19 for an illustration of the relevant parts of the WSDL generated by WebServicesAssembler.

How to Implement a Service Interface that Uses Streaming Attachments

Implementations of interfaces that include data as streaming attachments use the methods and classes of the oracle.webservices.attachments API to work with the attachment data.

Example 2-18 illustrates the implementation of the interface in Example 2-17 for a Web service that stores large image files in a local database. The implementation uses the getIncomingAttachments method to capture the incoming streaming attachment as an Attachment object. The getId method retrieves the attachment's metadata and getInputStream stores the stream image bytes.

Example 2-18 Service Implementation that Employs Streaming Attachments

class ImageStoreImpl {
    public void storeImage(String name, String desc, Attachments attachments) throws Exception {
        IncomingAttachments incomingAtts = attachments.getIncomingAttachments();
        {
            if (incomingAtts == null || !incomingAtts.hasNextAttachment())
                throw new Exception("Expected request attachments");
            Attachment imageAtt = incomingAtts.nextAttachment();
            String id = imageAtt.getId();
            DataHandler dataHandler = imageAtt.getDataHandler();
            InputStream imageStream = dataHandler.getInputStream();
            //-- Store image metadata and stream image bytes
            if (incomingAtts.hasNextAttachment())
                throw new Exception("Expected only one attachment");
        }
    }
}
Sample Generated WSDL for a Service with Streaming Attachments

Example 2-19 illustrates the relevant parts of the WSDL that WebServicesAssembler generates from the interface in Example 2-17. The presence of the <stream-attachments> extension in the WSDL indicates that the Web service supports streaming attachments.

See Also:

"WSDL Extensions for Streaming Attachments" for more information about the <stream-attachments> element and its schema.

Example 2-19 WSDL Elements for a Streaming Attachment

<message name="storeImageRequest">
    <part name="name" type="string"/>
    <part name="desc" type="string"/>
</message>
<portType name="ImageStorePortType">
    <operation name="storeImage">
        <input name="storeImageRequest" message="tns:storeImageRequest"/>
        <output name="storeImageResponse" message="tns:storeImageResponse"/>
    </operation>
</portType>
<binding name="ImageStoreBinding" type="tns:ImageStorePortType">
    <soap:binding style="rpc" />
    <operation name="addPerson">
        <soap:operation style="encoded" wsdl:required="true" />
        <sa:stream-attachments name="attachments" />
        <input name="storeImageRequest">
            <soap:body use="encoded" />
        </input>
        <output name="storeImageResponse">
            <soap:body use="encoded" />
        </output>
    </operation>
</binding>
How to Write Stub Code to Handle Streaming Attachments

The stub is the client side of the Web service. If the service wants to receive streamed attachments, the client must send them. If the service sends streamed attachments, the client must read them.

To handle streaming attachments, client code must create a new instance of an AttachementFactory and create an Attachments object. For a request attachment, the addAttachment method can be used to add the attachment to the output stream.

For a response attachment, the client code must create a new instance of an AttachementFactory and create an Attachments object. The client can capture the attachments with the iterator methods in the IncomingAttachments interface.

Example 2-20 illustrates stub code to store a streaming attachment. In the example, an AttachmentFactory is instantiated with the newInstance method and an Attachments object is created with the createAttachments method. The addAttachment method adds the data to the output stream.

Example 2-20 Client Code to Store a Streaming Attachment

public void storeImageFile (String fileName) {
    //--  Create the attachment objects
    AttachmentFactory factory = AttachmentFactory.newInstance();
    Attachments atts = factory.createAttachments();
    Attachment imageAtt = factory.createAttachment (fileName, "image/gif",
              new FileInputStream(fileName));
    atts.getOutgoingAttachments().addAttachment(imageAtt);
    storeImagePort.storeImage (fileName, "File stored at " + fileName, atts);
}

Steps for Assembling a Web Service that Supports Streaming Attachments Top Down

Assembling a Web service that supports streaming attachments follows the general steps described in "Assembling a Web Service from a WSDL" in the Oracle Application Server Web Services Developer's Guide. This section summarizes these steps.

To support streaming attachments, you must also edit the WSDL to add the <stream-attachments> element. Example 2-19 illustrates a WSDL that contains the <stream-attachments> element.

  1. Provide a WSDL from which the Web service will be generated.

  2. Edit the WSDL to add the elements that allow the Web service to support streaming attachments.

    "WSDL Extensions for Streaming Attachments" provides more information on the <stream-attachments> element and its schema.

  3. Use the WSDL as input to the WebServicesAssembler genInterface command.

  4. Compile the generated interface and type classes.

  5. Write the Java Service Endpoint interface for the Web service you want to provide.

  6. Compile the Java Service Endpoint interface.

  7. Generate the service by running the WebServicesAssembler tool with the topDownAssemble command.

  8. Deploy the service.

  9. Generate the client code.

Working with MTOM Encoded Attachments

In the current release, OracleAS Web Services and clients have the ability to process messages that are encoded in MTOM, MIME, and DIME format. MTOM (SOAP Message Transmission Optimization Mechanism) encoding allows binary content to be efficiently passed between the client and service.

This section has the following subsections:

Understanding MTOM Encoded Attachments

Binary content, such as an image in JPEG format, can be passed between the client and the service. In order to be passed, the binary content is typically inserted into an XML document as an xsd:base64Binary string. Transmitting the binary content in this format greatly increases the size of the message sent over the wire and is expensive in terms of the required processing space and time.

Using MTOM, binary content can be sent as a MIME attachment, which reduces the transmission size on the wire. The binary content is semantically part of the XML document. This is an advantage over SWA (SOAP Messages with Attachments), in that it enables you to apply operations such as WS-Security signature on the message.

Using MTOM to pass binary content as an attachment improves the performance of the Web services stack. Performance is not affected if an MTOM-encoded message does not contain binary content. For better interoperability, messages that do not contain binary content should not be MTOM encoded.

MTOM provides an optimized transmission mechanism for SOAP 1.2 messages with an envelope that contains elements of XML schema type xs:base64Binary. MTOM makes use of data handling mechanisms described in the following specifications:

  • XOP (XML-binary Optimized Packaging)—provides a mechanism to more efficiently serialize XML Infosets that have content of type xs:base64Binary.

  • DMCBDX (Describing Media Content of Binary Data in XML)—provides content type information for the binary data in the XML instance and schema. This information can be used to optimize the processing of binary data.

  • RRSHB (Resource Representation SOAP Header Block)—allows a SOAP message to carry a representation of a Web resource, such as a JPEG image, in a SOAP header block. When combined with MTOM and XOP, the Web resource contained in a RRSHB SOAP header block can be transmitted as a raw binary MIME attachment instead of an xs:base64Binary string in the SOAP header.

These specifications fulfill the requirements outlined in OSUCR (SOAP Optimized Serialization Use Cases and Requirements).

See Also:

The following Web sites provide more information on the specifications mentioned in this section.

How to Assemble Support for MTOM Encoded Attachments into a Web Service

You can use the WebServicesAssembler tool to add support for MTOM encoded attachments to a Web service and client. To do this, include the boolean mtomSupport attribute set to true in the WebServicesAssembler Ant target for top down, bottom up, or client Web service assembly.

The mtomSupport attribute is available only for the WebServicesAssembler topDownAssemble, assemble, and genProxy Ant tasks. It is not available on the command line.

Assembling Support for MTOM Encoded Attachments into a Web Service Bottom Up

Assembling support for MTOM encoded attachments into a Web service based on Java classes is similar to assembling any other service from Java classes. The only differences are that the Java classes work with binary data and you add the mtomSupport attribute to the assemble Ant task.

See Also:

The example in this section assumes that methods in the following Java interface and class files will be exposed as a Web service.

Example 2-21 illustrates the Java interface MtomBottomupSEI with methods to be exposed as a Web service. Note that this interface has a method that accepts a byte[] array as an input and returns the same byte array.

Example 2-21 Java Interface to be Exposed as a Web Service

public interface MtomBottomupSEI extends Remote{
    public byte[] echoBase64Binary(byte[] text) throws RemoteException;
}

Example 2-22 illustrates the Java class MtomBottomupImpl, the implementation of the interface to be exposed as a Web service:

Example 2-22 Java Class to be Exposed as a Web Service

public class MtomBottomupImpl {
    public byte[] echoBase64Binary(byte[] text) {
        return text;
    }
}

You can generate the Web service artifacts by running the WebServicesAssembler with the assemble Ant task. The following task exposes the interface and class to two ports, one for SOAP 1.2 and the other for SOAP 1.1. The port specification for SOAP 1.2 has mtomSupport enabled. The compiled implementation and class files reside in the mtom-bottomup-impl.jar.

<oracle:assemble appName="mtom-bottomup"
                 serviceName="mtom-bottomup"
                 input="mtom-bottomup-impl.jar"
                 style="rpc"
                 use="literal"
                 ear="mtom-bottomup.ear"
       >
       <oracle:porttype  interfaceName="mtom.service.MtomBottomupSEI" 
                         className="mtom.service.MtomBottomupImpl" >
         <oracle:port soapVersion="1.2" uri="MtomBottomupPort" 
                                        name="MtomBottomupPort" 
                                        mtomSupport="true"/>
         <oracle:port soapVersion="1.1" uri="MtomBottomupPortSoap11" 
                                        name="MtomBottomupPortSoap11" />
       </oracle:porttype>
   </oracle:assemble>

Example 2-23 illustrates part of the generated WSDL for this Web service. Note that the byte array is mapped to xsd:base64Binary as before. There is no WSDL or schema extension for MTOM.

Example 2-23 WSDL Fragment for a Web Service that Supports MTOM-Encoded Attachments

...
    <message name="MtomBottomupSEI_echoBase64Binary">
        <part name="text" type="xsd:base64Binary"/>
    </message>
    <message name="MtomBottomupSEI_echoBase64BinaryResponse">
        <part name="result" type="xsd:base64Binary"/>
    </message>
 ...

Example 2-24 illustrates part of the generated oracle-webservices.xml deployment descriptor for the Web service. Note that the port definition for MtomBottomupPort contains the line <mtom-support>true</mtom-support> while the other port, MtomBottomupPortSoap11, does not. The <mtom-support> element has a default value of false.

Example 2-24 oracle-webservices.xml Fragment for MTOM Encoded Web Service

...
<port-component name="MtomBottomupPort">
    <mtom-support>true</mtom-support>
    <operations>
        <operation name="echoBase64Binary" 
              input="{http://mtom.service/}echoBase64Binary"/>
    </operations>
</port-component>
<port-component name="MtomBottomupPortSoap11">
    <operations>
        <operation name="echoBase64Binary" 
               input="{http://mtom.service/}echoBase64Binary"/>
    </operations>
</port-component>
  ...

Assembling Support for MTOM Encoded Attachments into a Web Service Top Down

Assembling support for MTOM encoded attachments into a Web service top down is similar to any other top down assembly. The only differences are that the WSDL document is written to work with binary data and you add the mtomSupport attribute to the topDownAssemble Ant task.

See Also:

For example, presume that you have already provided a WSDL that can work with binary data as input to the genInterface Ant task. Also presume that you have implemented and compiled the service endpoint interface generated by the Ant task.

In the following topDownAssemble Ant task example, the Web service artifacts are assembled from the echo-service.wsdl file (illustrated in Example 2-25) and stored in the echo-service.ear file. The mtomSupport attribute is set on the definition of EchoTestPort to allow MTOM encoded binary attachments to be passed through that port.

<oracle:topDownAssemble appName="mtom-echo-service"
                        wsdl="echo-service.wsdl" 
                        ear=" echo-service.ear">
       <oracle:portType name="EchoTestPortType"
                        className="mtom.service.EchoTestImpl"
                        classFileName="src/mtom/service/EchoTestImpl.java">
           <oracle:port uri="/EchoTestPort" 
                        name="EchoTestPort"
                        mtomSupport="true">
           </oracle:port>
     </oracle:topDownAssemble> 

This Ant task creates the following method in the service endpoint interface:

...
  public byte[] echoPicture(byte[] picture);
... 

The following MTOM configuration is generated into the oracle-webservices.xml deployment descriptor:

<mtom-support>true</mtom-support>
Sample WSDL that Works with Binary Data

Example 2-25 illustrates a fragment of the echo-service.wsdl file. This WSDL defines a single portType with a single operation which accepts a xs:base64Binary request and returns a xs:base64Binary response. On the wire, the xs:base64Binary content will be in a MIME attachment part in binary format when MTOM is enabled.

Example 2-25 Sample WSDL that Works with Binary Data

...
    <wsdl:message name="echo-picture-Request">
        <wsdl:part name="picture" type="xsd:base64Binary"/>
    </wsdl:message>
    <wsdl:message name="echo-picture-Response">
        <wsdl:part name="picture" type="xsd:base64Binary"/>
    </wsdl:message>
    <wsdl:portType name="echo-servicePortType">
        <wsdl:operation name="echo-picture">
            <wsdl:input message="tns:echo-picture-Request"/>
            <wsdl:output message="tns:echo-picture-Response"/>
        </wsdl:operation>
    </wsdl:portType>
   ...

Assembling Support for MTOM Encoded Attachments into a Web Service Client

Assembling support for MTOM encoded attachments into a Web service client proxy is similar to assembling any other client proxy. The only differences are that the client code works with binary data and you add the mtomSupport attribute to the genProxy Ant task.

See Also:

In the following genProxy Ant task example, the client stub is assembled from the echo-service.wsdl file (illustrated in Example 2-25). The mtomSupport attribute is set to true on the definition of the EchoPort port. This will generate a proxy which has MTOM enabled: when request messages contain relevant content, they will be sent from the EchoPort encoded in MTOM format.

...
<oracle:genProxy wsdl="echo-service.wsdl">
     <oracle:port name="EchoPort" mtomSupport="true"/>
</oracle:genProxy>
...

Programatically Overriding MTOM Support for a Web Service Client

You can enable or disable MTOM support in the client by using the boolean MTOM_SUPPORT property in the oracle.webservices.ClientConstants class. This property enables a client stub to specify whether requests will be packaged in MTOM/XOP encoding. For examples of how to use the MTOM_SUPPORT property, see "How to Pass MTOM Encoded Attachments in Static Stub and Dynamic Proxy Clients".

How to Work with MTOM Encoded Attachments Programatically

The following sections describe how you can use the Oracle implementation of the SOAP with Attachments API for Java (OraSAAJ) to work with MTOM encoded attachments.

Understanding the OraSAAJ API for MTOM Encoded Attachments

The OraSAAJ API provides methods and properties that enable clients and services to work with binary attachments in MTOM-encoded format. These methods and properties are described in the following sections.

MTOM_SUPPORT Property

The oracle.webservices.ClientConstants class provides a boolean MTOM_SUPPORT property which allows a client stub to specify whether requests will be packaged in MTOM/XOP encoding. This property is set on the port that will be sending the requests.

public static final String MTOM_SUPPORT="oracle.webservices.mtomSupport"; 

If the value of the property is set to true, then requests are encoded in MTOM/XOP format. The default value is false.

See Also:

"How to Pass MTOM Encoded Attachments in Static Stub and Dynamic Proxy Clients" provides examples of how to use the MTOM_SUPPORT property.

PACKAGING_STYLE and ATTACHMENT_STYLE_PACKAGING Properties

The abstract oracle.j2ee.ws.saaj.soap.MessageImpl class is an Oracle proprietary extension of the javax.xml.soap.SOAPMessage class. Among other features, the MessageImpl class provides the PACKAGING_STYLE and ATTACHMENT_STYLE_PACKAGING properties to indicate the encoding format into which the message should be serialized.

public abstract class MessageImpl extends SOAPMessage {
   ...
 public static final String ATTACHMENT_STYLE_PACKAGING="AttachmentStylePackaging";
 public static final String PACKAGING_STYLE = "PackagingStyle"; public static final String MTOM = "MTOM";
 public static final String DIME = "DIME"; public static final String MIME = "MIME";   ...}  

The Oracle proprietary MessagImpl.PACKAGING_STYLE property enables you to serialize messages into a number of different encoding formats. The encoding format is applied to a SOAPMessage object. The possible values for MessageImpl.PACKAGING_STYLE are:

  • MessageImpl.MTOM—serializes a SOAPMessage into MTOM format.

  • MessageImpl.MIME (default)—serializes a SOAPMessage into MIME format.

  • MessageImpl.DIME—serializes a SOAPMessage into DIME format.

For example, the following will encode the request message into MTOM format if it contains relevant content.

...
request.setProperty(MessageImpl.PACKAGING_STYLE, MessageImpl.MTOM);
...

See Also:

"How to Pass Attachments with Binary Content in Clients that Connect with SOAPConnection" provides examples of how to use the MessageImpl.PACKAGING_STYLE property.

The boolean MessageImpl.ATTACHMENT_STYLE_PACKAGING property enables you to force a message to take the encoding style specified by the MessageImpl.PACKAGING_STYLE property. If the MessageImpl.ATTACHMENT_STYLE_PACKAGING property is set to true, the message will be encoded in the format specified by MessageImpl.PACKAGING_STYLE even if it does not contain relevant content. The default value for this property is false.

For example, the following code sample will force the contents of the msg message to be encoded into MTOM format.

...
msg.setProperty(MessageImpl.PACKAGING_STYLE, MessageImpl.MTOM);
msg.setProperty(MessageImpl.ATTACHMENT_STYLE_PACKAGING, "true");
...

If the MessageImpl.ATTACHMENT_STYLE_PACKAGING property is set to true and the MessageImpl.PACKAGING_STYLE property is not present, then the message will be encoded in MIME format (the default value of MessageImpl.PACKAGING_STYLE).

See Also:

"How to Force a Message Encoding" for examples of how to use the MessageImpl.ATTACHMENT_STYLE_PACKAGING property.

Table 2-3 describes the expected output when you use the MessageImpl.ATTACHMENT_STYLE_PACKAGING property with MessageImpl.PACKAGING_STYLE.

Table 2-3 Resulting Message Formats for Different PACKAGING_STYLE and ATTACHMENT STYLE_PACKAGING Values

PACKAGING_STYLE Property Value ATTACHMENT_STYLE_PACKAGING Property Value Resulting Message Format

not present or MTOM

not present (default) or false

  • If the MTOM attachment exists, then the user receives a message in MTOM format.

  • If SWA attachment, then the user receives a message in MIME format.

  • If the attachment is neither MTOM or SWA, or if there is no attachment, then the user receives a message in Envelope-only format.

MIME

not present (default) or false

  • If the attachment is in SWA format, then the user receives a message in MIME format.

  • If there is no SWA attachment or if the attachment is in another format, then the user receives a message in Envelope-only format.

DIME

not present (default) or false

  • If the attachment is in SWA format, then the user receives a message in DIME format.

  • If there is no SWA attachment or if the attachment is in another format, then the user receives a message in Envelope-only format.

MTOM

true

The user receives a message in MTOM format.

MIME

true

The user receives a message in MIME format.

DIME

true

The user receives a message in DIME format.

not present

true

The user receives a message in MIME format.


OracleSOAPElement getDataHandler and setDataHandler Methods

The oracle.webservices.soap.OracleSOAPElement interface is an Oracle proprietary extension of the javax.xml.soap.SOAPElement interface. The interface contains methods for working with attachments with binary content (MTOM/XOP).

The interface has the following signature:

public interface OracleSOAPElement extends SOAPElement{
    public DataHandler getDataHandler() throws SOAPException;
    public void setDataHandler(DataHandler datahandler);

Note:

You do not have to use the OracleSOAPElement API if you do not need to access the binary content directly. If you use the DOM or SAAJ APIs, then binary content in MTOM encoding can be accessed like any other message content.

For example, assume that you are using the DOM or SAAJ APIs and you receive a message with an MTOM-encoded attachment. You can use a method such as SOAPElement.getValue to get a base-64 encoded binary string instead of the binary object.

The setDataHandler method sets the given DataHandler object as the data handler for this OracleSOAPElement object. Typically, a data handler is automatically set on an incoming message. When a message is created and populated with content, the setDatahandler method can get information from various data sources and add them to the message.

When the SOAPMessage containing this element is serialized into MTOM/XOP format, a MIME part will be created out of this DataHandler. When this SOAPMessage is serialized into other formats, then the bytes read from this DataHandler will be encoded into a base-64 string and set as the only child of this OracleSOAPElement.

The setDataHandler method can throw an IllegalArgumentException if the data handler is invalid.

See Also:

See "PACKAGING_STYLE and ATTACHMENT_STYLE_PACKAGING Properties" for a description of the properties that can be set on the SOAPMessage to serialize it into various formats.

The getDataHandler method can return either the DataHandler object created from the MTOM/XOP attachment associated with this OracleSOAPElement object or text in base-64 binary format.

This method assumes that the element is of type xsd:base64Binary, either in native base-64 string form or MTOM/XOP attachment form. If you call this method on other types of elements, then the results are undefined. This method can be called regardless of whether the associated SOAPMessage is packaged in MTOM/XOP format.

The getDataHandler method throws a SOAPException if these conditions are not met. For example, an exception is thrown if this OracleSOAPElement object has no data or if it has child elements.

See Also:

"How to Use the OraSAAJ API to Work With MTOM Encoded Attachments" provides information and examples of how to use the methods in the OracleSOAPElement interface.

How to Use the OraSAAJ API for Attachments with Binary Content in Client Code

This section describes how to use the Oracle extensions to the SAAJ (OraSAAJ) API for attachments with binary content in client code. These extensions allow a Web service to work with SOAP 1.2 messages.

How to Pass MTOM Encoded Attachments in Static Stub and Dynamic Proxy Clients

To enable or disable the ability of a Web Service client to send MTOM encoded requests, the OraSAAJ API provides the boolean MTOM_SUPPORT property in the oracle.webservices.ClientConstants package:

public static final String MTOM_SUPPORT = "oracle.webservices.mtomSupport";

Set this property on the port that will be sending the messages. If the property is set to true, then any messages sent from the port will be MTOM encoded. The default value is false.

The property can be used in client code to override MTOM support in a client that was assembled to send MTOM encoded requests, or to enable support in a client that was assembled without MTOM.

See Also:

Example 2-26 illustrates a fragment of static stub client code. It is assumed that the client was originally assembled without MTOM support. In the code fragment, the MTOM_SUPPORT property is set on the EchoPort port before the client is invoked. Any messages sent from the EchoPort port will be in MTOM-encoded format.

Example 2-26 MTOM_SUPPORT Property in Static Stub Client Code

...
//obtain the service from the ServiceFactory
ServiceFactory serviceFactory = ServiceFactory.newInstance();
EchoService service = (EchoService)serviceFactory.createService(null, EchoService.class);

// get the port
Object port = service.getEchoPort();

// enable MTOM support
((OracleStub)port).setProperty(MTOM_SUPPORT, "true");
 
// invoke the stub
byte[] response = ((EchoPort)port).echoPicture(new byte[picture]);
...
How to Pass Attachments with MTOM Encoded Content in J2EE Clients

J2EE clients can pass attachments with MTOM encoded content by setting the boolean property oracle.webservices.mtomSupport to true in any of the Oracle proprietary client deployment descriptor files. These files are:

  • orion-web.xml for Web clients

  • orion-ejb-jar.xml for EJB clients

  • orion-application-client.xml for application clients

To make a J2EE client aware of MTOM support, enter the property in the deployment descriptor file as a stub property in a <service-ref-mapping> clause.

Example 2-27 illustrates a sample configuration in an orion* file that enables the client to send requests in MTOM encoded format. In the sample, service_name represents the Web service's service name.

Example 2-27 Enabling MTOM in a J2EE Client

...
<service-ref-mapping name="service_name">
  <port-info>
    <stub-property>
      <name>oracle.webservices.mtomSupport</name>
      <value>true</value>
    </stub-property>
  </port-info>
</service-ref-mapping>
...
How to Pass Attachments with Binary Content in Clients that Connect with SOAPConnection

The SOAPConnection object establishes a point-to-point connection that a Web service client can use to send messages to a remote party, such as a URL. This type of connection does not require a messaging provider. For this reason, a client that uses a SOAPConnection in OraSAAJ directly must serialize the request SOAPMessage into the appropriate format before calling the SOAPConnection.call method.

To serialize the message, apply the Oracle proprietary MessagImpl.PACKAGING_STYLE property to the SOAPMessage. The value of the property indicates the format into which the message will be serialized. The possible values for MessageImpl.PACKAGING_STYLE are:

  • MessageImpl.DIME—serializes a SOAPMessage into DIME format

  • MessageImpl.MIME— (default) serializes a SOAPMessage into MIME format

  • MessageImpl.MTOM—serializes a SOAPMessage into MTOM format

The MessageImpl.PACKAGING_STYLE property produces a message in the specified encoding only when the relevant content exists. If the content is not provided, then you might get a message in an unexpected format. To force a message into a particular encoding, see the following section, "How to Force a Message Encoding".

Example 2-28 illustrates the use of the MessageImpl.PACKAGING_STYLE property. The code sample creates a request of type SOAPMessage. After adding binary content to the request message, the setProperty method identifies the encoding into which the message should be serialized. In this case, the message is serialized into MTOM encoding. The connection is then made to the remote party and the call is made with the serialized request.

Example 2-28 MessageImpl.PACKAGING_STYLE Property in Client Code

...
SOAPMessage request = MessageFactory.newInstance().createMessage();
...
// add some binary content 
...
request.setProperty(MessageImpl.PACKAGING_STYLE, MessageImpl.MTOM);
SOAPConnection conn = SOAPConnectionFactory.newInstance().createConnection();
SOAPMessage response = sc.call(request, endpoint);
...

See Also:

"PACKAGING_STYLE and ATTACHMENT_STYLE_PACKAGING Properties" provides more information on the PACKAGING_STYLE property.

How to Force a Message Encoding

The MessageImpl.PACKAGING_STYLE property produces a message in the specified encoding only when the relevant content exists. If the relevant content is not provided, then you might get a message in an unexpected format.

For example, assume that you provide binary content for a message msg, then call the MessageImpl.PACKAGING_STYLE property with the MessageImpl.MTOM value:

msg.setProperty(MessageImpl.PACKAGING_STYLE, MessageImpl.MTOM);

You will get a message in MTOM encoding.

If you provide a regular MIME attachment instead of binary, then you will receive a SWA MIME message. If you do not provide an attachment, then you will receive a SOAP-only message.

If you want to force a specific encoding on a message even if the relevant content does not exist, use the boolean MessageImpl.ATTACHMENT_STYLE_PACKAGING property with the MessageImpl.PACKAGING_STYLE property. For example, the following code sample forces the message msg to be encoded in MIME format.

...
SOAPMessage msg = MessageFactory.newInstance().createMessage();
...
// add content to the message
...
msg.setProperty(MessageImpl.PACKAGING_STYLE, MessageImpl.MIME);
msg.setProperty(MessageImpl.ATTACHMENT_STYLE_PACKAGING, "true");
...

See Also:

"PACKAGING_STYLE and ATTACHMENT_STYLE_PACKAGING Properties" provides more information on the ATTACHMENT_STYLE_PACKAGING property.

How to Use the OraSAAJ API to Work With MTOM Encoded Attachments

The OraSAAJ API enables a Web service to work with SOAP 1.2 messages. Artifacts that use this API and SOAP 1.2 messages, such as handlers, interceptors, provider services, and BPEL, can use the oracle.webservices.soap.OracleSOAPElement interface to work with attachments with binary content.

The OracleSOAPElement interface extends the javax.xml.soap.SOAPElement interface.

This section has the following subsections:

See Also:

How to Add Binary Content with the OracleSOAPElement API

To add binary content, such as xs:base64Binary type data to a message, use the OracleSOAPElement.setDataHandler method. To encode the message into MTOM format, use the MessageImpl.PACKAGING_STYLE property.

Example 2-29 illustrates adding binary content to a message then encoding it as an attachment in MTOM format. A picture element of type SOAPElement is added to body of a SOAP message. A BufferedImage image object is defined with a height and width of 10, and a color model of one bit for each pixel, eight pixels to a byte (TYPE_BYTE_BINARY). The picture element is cast to a OracleSOAPElement, so that the setDataHandler method can be applied. This method loads the file (image/jpeg is the MIME content type that corresponds to a java.awt.Image). The MessageImpl.PACKAGING_STYLE property indicates that the binary attachment will be encoded in MTOM format. The resulting message is written to the output stream baos.

Example 2-29 Adding Binary Content to a Message as an MTOM-Encoded Attachment

...
SOAPElement picture = msg.getSOAPBody().addChildElement("Picture");
BufferedImage image = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_BINARY);
((OracleSOAPElement)picture).setDataHandler(new DataHandler(image, "image/jpeg"));
        msg.setProperty(MessageImpl.PACKAGING_STYLE, MessageImpl.MTOM);
        msg.writeTo(baos);
...
How to Access Binary Content with the OracleSOAPElement API

To access content from an OracleSOAPElement, use the OracleSOAPElement.getDataHandler method. The method simply provides a handler for the message data; the data does not have to be encoded.

Example 2-30 illustrates using the OracleSOAPElement.getDataHandler method to get message content. The method assumes that the message msg has an attachment that contains xs:base64Binary content, in this case, a java.awt.Image. The code gets the contents of the child elements of a SOAPMessage and stores them in a OracleSOAPElement picture. The OracleSOAPElement.getDataHandler method is then used to get the content from picture and store it in the Image object.

Example 2-30 Accessing a Message Attachment that Contains Binary Content

...
OracleSOAPElement picture =
          (OracleSOAPElement)msg.getSOAPBody().getChildElements().next();
Image image = (Image)picture.getDataHandler().getContent();
   ...

Working with DIME-Encoded Attachments

This section has the following subsections:

Understanding DIME-Encoded Attachments

Direct Internet Message Encapsulation (DIME) is a format for streaming multi-part message attachments over the wire. DIME can be applied to SOAP messages with attachments. DIME separates each record, such as a SOAP message or attachment, with a simple binary SOAP header that describes the size and type of the payload. DIME also allows a given piece of payload to be broken into multiple records. This allows the sender to stream data through a buffer of constrained size.

Compared to the multipart-MIME encoding format which OracleAS Web Services uses by default, DIME requires much less processing effort to encode or decode.

OracleAS Web Services lets you choose between supporting interoperable DIME-encoded messages and messages with Oracle proprietary DIME encoding.

  • Interoperable DIME encoding for messages with attachments is implemented by adding extensions to the WSDL.

  • Oracle proprietary DIME encoding is implemented by allowing WebServicesAssembler to generate code that applies DIME encoding to all SOAP messages with attachments.

How to Implement Interoperable DIME-Encoded Messages

WSDL extensions for DIME-encoded messages are an implementation of Microsoft's DIME support. This technique creates messages with attachments that are interoperable with other vendors, particularly Microsoft, who implement DIME extensions in the WSDL. The extensions cause any binary data in the envelope to be extracted and placed in attachments. These messages and their attachments are then encoded in DIME.

The "WSDL Extension for SOAP in DIME" specification defines a DIME element, <dime:message>. If this element is added to the WSDL, then any binary data in the SOAP message is automatically removed and put into attachments. The message and its attachments are then sent in DIME format instead of the default multipart-MIME format.

See Also:

The <dime:message> element can be inserted into the <wsdl:input> and/or <wsdl:output> elements of a Web service operation bindings definition. Table 2-4 describes the attributes that <dime:message> must include.

Table 2-4 <dime:message> Required Attributes

Attribute Description

layout="uri"

Specifies how the primary SOAP message references the attachments in a DIME message. The following are the possible values for the URI.

  • http://schemas.xmlsoap.org/ws/2002/04/dime/closed-layout—Specifies that the primary SOAP message references all parts of a DIME message in the proper order.

  • http://schemas.xmlsoap.org/ws/2002/04/dime/open-layout—Specifies that the DIME message can include additional attachments, even though they are not referenced by the SOAP message. These additional attachments must follow all of the attachments in the DIME message that are referenced by the SOAP message.

wsdl:required="true"

Indicates that the presence of a WSDL is required. This attribute must be set to true.


Example 2-31 illustrates a WSDL skeleton with the extensions for DIME encoding highlighted in bold.

Example 2-31 WSDL Skeleton, with the Extensions for DIME Encoding

<wsdl:definitions ...>
 <wsdl:binding ...>
  <soap:binding .../>
  <wsdl:operation ...>
    <soap:operation .../>
    <wsdl:input>
     <dime:message layout="uri" wsdl:required="true"/>?
     <-- extensibility elements -->
    </wsdl:input>
    <wsdl:output>
     <dime:message layout="uri" wsdl:required="true"/>?
     <-- extensibility elements -->
     </dime:message>
    </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
</wsdl:definitions>

Limitations on OracleAS Web Services Support for Interoperable Dime Encoded Messages

  • Support for DIME encoding can be assembled into a Web service only from WSDL (top down). It cannot be assembled into a Web service bottom up.

  • OracleAS Web Services does not support content type definition with DIME as specified by the following namespace:

    http://schema.xmlsoap.org/ws/2002/04/content-type.

How to Implement Oracle Proprietary DIME-Encoded Messages

The WebServicesAssembler supports the DIME-encoded format by providing a useDimeEncoding argument. This argument will apply DIME encoding to all streaming SOAP messages with attachments in a generated service or stub.

The messages generated with the useDimeEncoding argument are not interoperable and are incompatible with non-Oracle Web services or earlier versions of Oracle Application Server. Generating a Web service with this argument is useful for in-house projects where performance is key.

See Also:

"useDimeEncoding" in "General Web Services Assembly Arguments" in the Oracle Application Server Web Services Developer's Guide.

Working with Attachments in WSIF

For information on enabling WSIF clients to handle message attachments, see "How to Add Message Attachments in WSIF". This section contains the following subsections:

Limitations

See "Working with Message Attachments".

Additional Information

For more information on: