Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
HydraExpress Web Service Development Guide
Rogue Wave web site:  Home Page  |  Main Documentation Page

17.3 Working with Attachments

HydraExpress represents each object defined as a MIME attachment in a WSDL document as an instance of rwsf::MessageAttachment. This class encapsulates the message payload and Content-Type information, and may also include Content-Id or Content-Location data.

To send a SOAP message with an attachment, follow these steps:

  1. Define the attachment in WSDL, including the abstract definitions that describe the operation in which the attachment is sent, and the concrete definition that describes the MIME binding.

  2. Generate code.

  3. Implement and run your service.

This section discusses each of these steps. The discussion is based on the shipped example MIME located in your <installdir>\examples\webservices\MIME directory. This directory includes a mime.wsdl file as well as sample implementations provided so you can quickly build and test the example.

17.3.1 Example Service Description

The MIME example is a basic request-response client-service example, using a MIME binding. It includes two operations, AddDocument to send an explicitly-referenced MIME attachment, and GetDocuments to return a list of links to unreferenced MIME attachments (Section 17.3.3). The latter illustrates the use of the schema type swaRef defined by the WS-I Attachments Profile 1.0 providing an interoperable way to identify a message attachment.

17.3.2 Define the Attachment in WSDL

To define an attachment in WSDL, first define its abstract aspects, including its Schema type, its WSDL message parts and the operation(s) that will use it. Finally, define the concrete MIME bindings.

17.3.2.1 Define the Schema Type

First, define the object's type either in the WSDL file's types element, or in an associated or embedded XML Schema. Here's an excerpt from mime.wsdl in the MIME directory. This example illustrates both traditional attachments as specified by SwA, as well as unreferenced attachments as described by WS-I Attachments Profile 1.0.

Note the simple type swaRef. This a schema type defined by the WS-I Attachments Profile 1.0 that identifies any associated message attachment. The restriction xsd:anyURI references an attachment in the message. By using a common type, all recipients know that the referenced message is an attachment. (For more information, see http://www.ws-i.org/Profiles/AttachmentsProfile-1.0-2004-08-24.html#Referencing_Attachments_from_the_SOAP_Envelope). This type is used in unreferenced attachments (see Section 17.3.3).

The WSDL defines two complex types, DocumentPair and DocumentPairList, which is simply a list of elements of type DocumentPair. DocumentPair contains two elements, DocumentName, the MIME document's name, and DocumentRef, MIME document's key. DocumentRef is of type swaRef, which identifies it as a link to an attachment. In addition, the element Documents is declared, of type DocumentPairList.

17.3.2.2 Define the WSDL Message Parts and Operation

The mime.wsdl document defines two messages, Document and DocumentList, as follows:

The message Document contains two parts, including a name as an xsd:string, and a document of type xsd:base64binary. Message DocumentList contains one part, documents, which is of type DocumentPairList as defined in the above types element.

The messages Document and DocumentList are passed in two request/response operations:

The WSDL excerpt above defines two operations, AddDocument and GetDocuments. The operation AddDocument sends a document name and part containing the document's contents. The contents are sent as an explicitly referenced MIME attachment. The operation GetDocuments returns a MIME document that contains a list of document names and keys, along with a set of unreferenced MIME attachments. We can then look up the documents contents in the MIME attachments list via the swaRef links provided in the DocumentList.

17.3.2.3 Define the MIME Bindings

The MIME binding defines the MIME type multipart/related for the message response. Let's look at the binding for the AddDocument and GetDocuments operations:

//1

Defines the binding for the input message's multipart mime attachment, consisting of two mime parts, one the body of the message, the other the image.

//2

Defines a referenced attachment (see below), tied to the document part. Note the type indicates that any MIME type is allowed for this attachment.

17.3.3 Generate Code and Manipulate the Attachment

Use rwsfgen to generate code for this project. (For information on how to generate code, see Section 7.2.2.). If you use the provided HydraExpress project file example-project.xml, HydraExpress places the generated code into a code generation directory MIMEExample.

In the client and server sample implementations, HydraExpress generates service operation methods that take as parameters instances of rwsf::MessageAttachment.

The resulting code differs depending on whether the attachment is referenced or unreferenced:

17.3.3.1 Sending a Referenced Attachment

Here's the code for the method addDocument in the provided sample server implementation (located in the root directory of the MIME example), DocumentManagerPortTypeImp.cpp:

As line //1 shows, the referenced attachment generates the document parameter (labeled as document_in since it is an input parameter) as an rwsf::MessageAttachment instance. This rwsf::MessageAttachment object represents the whole part as a MIME attachment.

The method implementation simply adds the document to an internal data structure used by HydraExpress to hold state between service calls.

17.3.3.2 Retrieving an Unreferenced Attachment

Let's look at the WSDL binding for a method getDocuments that returns a MIME attachment:

Note that, unlike the addDocument example above, this binding does not list a mime:content element and does not reference a part. This is called an "unreferenced attachment", while the example for addDocument showcases a referenced attachment where the MIME elements directly reference the part.

Here's the code that is provided for the client operation getDocuments() in the sample client implementation DocumentManagerPortClient.cpp. Recall that the getDocuments method returns a MIME document that contains a list of document names and keys, and a set of unreferenced MIME attachments.

//1

Note that the response is an instance of tns::Documents, which is defined in the WSDL as an instance of a tns::DocumentPairList and is therefore generated as a std::vector of tns::DocumentPair elements.

//2

Make the actual client call to the web service operation. Returns the DocumentPairList containing the documents.

//3

Begins iteration over all items in the Document list, and prints to standard out that the document has been received.

//4

Here, we extract the Content-ID for the associated attachment. Remember that the variable documentRef is of type tns:swaRef, and so represents any associated message attachment using a URI as a reference.

//5

Retrieves the message attachment as an instance of rwsf::MessageAttachment, based on the URL specified in the SOAP message. Note that the attachment is returned using rwsf::CallInfo's method getResponseAttachment based on its Content-ID.

//6

Retrieves the attachment if it's found.

17.3.3.3 Retrieving a Referenced Attachment

The GetDocuments method illustrates client-side working with unreferenced attachments. If the WSDL described another operation called getDocument which accessed a referenced attachment it might look like this:

This getDocument service operation would take a documentKey as input and return the full attachment in the part called document. The generated getDocument service operation method would return the part as an rwsf::MessageAttachment instance.

So we could write the invoke_getDocument() client implementation code to look like:

17.3.4 Build and Run the Example

Build and run the example, as usual. For basic information on compiling and deploying, see Section 8.2.3 and Section 8.2.4.

Before building this example, remember to copy the provided sample files from the <installdir>\examples\webservices\MIME directory to the directory in which you generated code (called MIMEExample below), allowing the provided files to overwrite the generated files, as follows:

DocumentManagerPortTypeImp.h Copy to MIMEExample\app\server
DocumentManagerPortTypeImp.cpp Copy to MIMEExample\app\server
DocumentManagerPortClient.cpp Copy to MIMEExample\app\client

Run the client from the MIMEExample\bin directory:



Previous fileTop of DocumentContentsIndex pageNext file

Copyright © Rogue Wave Software, Inc. All Rights Reserved.

The Rogue Wave name and logo are registered trademarks of Rogue Wave Software, and HydraExpress is a trademark of Rogue Wave Software. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.