Oracle® Application Server Advanced Web Services Developer's Guide 10g (10.1.3.1.0) Part Number B28975-02 |
|
|
View PDF |
This chapter has the following sections.
This section contains the following subsections.
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:
http://www.w3.org/TR/SOAP-attachments
for the SOAP with Attachments (SWA
) specification.
http://www.ws-i.org/Profiles/AttachmentsProfile-1.0-2004-08-24.html
for the WS-I Attachments Profile 1.0 and the definition of the swaRef
format.
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
.
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 useswaRef
.OracleAS Web Services enables you to assemble Web services up that can pass MIME attachments with swaRef
. This is described in the following sections.
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.
Provide a WSDL from which you want to assemble a Web service.
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"/>
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 typewsi: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>
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.
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:
"How to Create a New Instance of AttachmentPart" for information on how to create an instance of AttachmentPart
.
Example 2-4 for a sample implementation of a generated service endpoint interface, with code that creates a new instance of AttachmentPart
.
A WSDL that uses swaRef
attachments must have the following characteristics.
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-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; ... }
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; }
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.
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 passswaRef
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.
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.
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.
If you used the genWsdl
command to generate the WSDL, you can now inspect the file.
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.
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-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> ...
This section contains the following subsections:
Steps for Assembling a Web Service with SWA Attachments Top Down
Sample Generated Interface with Parameters that Can Pass SWA 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 |
|
text/plain, application/plain |
|
text/xml |
|
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.
Provide the WSDL from which you want to generate a Web service.
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>
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.
Implement the generated service endpoint interface.
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>
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; }
This section describes how to add MIME type attachments to SOAP fault messages. It contains the following subsections:
Steps for Assembling SOAP Faults with Attachments into a Web Service Top Down
How to Implement a Method that Throws Faults with Attachments
Note:
In OracleAS Web Services, you can add only MIME type attachments to SOAP fault messages.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.The following general steps describe how to add attachments to SOAP fault messages and generate them into the service endpoint interface.
Provide the WSDL that you want to work with.
Edit the WSDL operation that you want to throw a fault with attachment content.
Declare the output element that will contain attachment content in the <wsdl:output.../>
clause. The clause must contain <mime:multipartRelated>
content.
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.
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
.
Implement the interface.
In the implementation, include code to perform the following tasks.
Create a new instance of the exception that implements oracle.webservices.attachments.AttachmentFault
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.
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.
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>
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; }
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. } }
This section contains the following subsections:
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--
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.
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 |
---|---|
|
The |
|
This factory class creates instances of |
|
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. |
|
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. |
|
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. |
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(); }
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(); }
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(); }
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; }
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); }
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>
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
Steps for Assembling a Web Service that Supports Streaming Attachments Top Down
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.
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.
Write the implementation of the service.
"How to Implement a Service Interface that Uses Streaming Attachments" provides more information on this step.
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.
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.
Deploy the service and bind the application.
Generate the client-side code.
Compile and run the client.
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.
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"); } } }
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>
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); }
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.
Provide a WSDL from which the Web service will be generated.
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.
Use the WSDL as input to the WebServicesAssembler genInterface
command.
Compile the generated interface and type classes.
Write the Java Service Endpoint interface for the Web service you want to provide.
Compile the Java Service Endpoint interface.
Generate the service by running the WebServicesAssembler tool with the topDownAssemble
command.
Deploy the service.
Generate the client code.
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:
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.
MTOM (SOAP Message Transmission Optimization Mechanism) specification:
XOP (XML-binary Optimized Packaging) specification:
DMCBDX (Describing Media Content of Binary Data in XML) specification:
RRSHB (Resource Representation SOAP Header Block) specification:
OSUCR (SOAP Optimized Serialization Use Cases and Requirements):
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 Top Down
Assembling Support for MTOM Encoded Attachments into a Web Service Client
Programatically Overriding MTOM Support for a Web Service Client
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 Oracle Technology Network provides a "How To" which demonstrates how to assemble support for MTOM encoded attachments into a Web service bottom up from Java classes and how to assemble a client. you can find the "How To" at the following Web site:
http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html#webservices
For a detailed description of the steps involved in assembling a Web service bottom up, see "Assembling a Web Service from Java Classes" in the Oracle Application Server Web Services Developer's Guide.
For more information on the mtomSupport
Ant attribute, see the chapter "Using WebServicesAssembler" in the Oracle Application Server Web Services Developer's Guide.
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 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 a detailed description of the steps involved in assembling a Web service top down, see "Assembling a Web Service from WSDL" in the Oracle Application Server Web Services Developer's Guide.
For more information on the mtomSupport
Ant attribute, see the chapter "Using WebServicesAssembler" in the Oracle Application Server Web Services Developer's Guide.
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>
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 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:
For a detailed description of the steps involved in assembling a Web service client proxy, see "Assembling a J2SE Web Service Client" in the Oracle Application Server Web Services Developer's Guide.
For more information on the mtomSupport
Ant attribute, see the chapter "Using WebServicesAssembler" in the Oracle Application Server Web Services Developer's Guide.
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>
...
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".
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.
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.
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.
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 |
|
MIME |
not present (default) or |
|
DIME |
not present (default) or |
|
MTOM |
|
The user receives a message in MTOM format. |
MIME |
|
The user receives a message in MIME format. |
DIME |
|
The user receives a message in DIME format. |
not present |
|
The user receives a message in MIME format. |
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 theOracleSOAPElement
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.
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
How to Pass Attachments with MTOM Encoded Content in J2EE Clients
How to Pass Attachments with Binary Content in Clients that Connect with SOAPConnection
How to Use the OraSAAJ API to Work With MTOM Encoded Attachments
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:
"How to Pass Attachments with MTOM Encoded Content in J2EE Clients" provides information on how to use this property to pass MTOM encoded attachments in J2EE clients.
"Assembling Support for MTOM Encoded Attachments into a Web Service Client" provides information on how to assemble MTOM support into Web service clients.
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]);
...
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.
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:
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.
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.
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:
"OracleSOAPElement getDataHandler and setDataHandler Methods" provides more information on this interface.
"OraSAAJ APIs" in the Oracle Application Server Web Services Developer's Guide provides more information on the OraSAAJ APIs and the contents of the oracle.webservices.soap
package.
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); ...
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.
This section has the following subsections:
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.
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:
http://www.gotdotnet.com/team/xml_wsspecs/dime/WSDL-Extension-for-DIME.htm
for the "WSDL Extension for SOAP in DIME" specification.
http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/
for the schema that defines the WSDL extensions for SOAP in DIME.
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.
|
wsdl:required="true" |
Indicates that the presence of a WSDL is required. This attribute must be set to |
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>
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
.
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.
For information on enabling WSIF clients to handle message attachments, see "How to Add Message Attachments in WSIF". This section contains the following subsections:
For more information on:
enabling WSIF clients to handle attachments, see Web Services Invocation Framework, see Chapter 9, "Using Web Services Invocation Framework".
assembling a Web service top down, see "Assembling a Web Service from a WSDL" in the Oracle Application Server Web Services Developer's Guide.
using Java classes to assemble a Web service, see "Assembling a Web Service with Java Classes" in the Oracle Application Server Web Services Developer's Guide.
using EJBs to assemble a Web service, see "Assembling a Web Service with EJBs" in the Oracle Application Server Web Services Developer's Guide.
using JMS topics and destinations to assemble a Web service, see "Assembling Web Services with JMS Destinations" in the Oracle Application Server Web Services Developer's Guide.
using database resources, such as PL/SQL packages, SQL queries, DML statements, Oracle Streams AQ, or server-side Java classes, to assemble a Web service, see "Assembling Database Web Services" in the Oracle Application Server Web Services Developer's Guide.
assembling a J2EE Web Service client, see "Assembling a J2EE Web Service Client" in the Oracle Application Server Web Services Developer's Guide.
assembling a J2SE Web service client, see "Assembling a J2SE Web Service Client" in the Oracle Application Server Web Services Developer's Guide.
using WebServicesAssembler commands to assemble Web service artifacts, see "Using WebServicesAssembler" in the Oracle Application Server Web Services Developer's Guide.