Creating Web Services and Web Clients in Caché
Using SOAP with Attachments
[Back] [Next]
Go to:

In your Caché web clients and web services, you can add and use attachments to SOAP messages by using the Caché support for SOAP with Attachments, instead of using the Caché MTOM support, as described in the previous chapter.

This method requires more work than using MTOM because your code must directly manage the MIME parts used as attachments.
For a link to the specifications for the SOAP with Attachments standard, see Standards Supported in Caché,” in the first chapter of this book.
Sending Attachments
When you use the Caché support for the SOAP with Attachments standard, you use the following process to send attachments:
  1. Create the attachments. To create an attachment:
    1. Use a stream object to represent the attachment data. The class you use depends on the exact interface you need to obtain the stream data. For example, you might use %Library.FileCharacterStream to read the contents of a file into a stream.
    2. Create a MIME part, which is an instance of %Net.MIMEPart.
    3. For the MIME part:
      • Set the Body property equal to your stream object. Or set the Parts property, which must be a list of instances of %Net.MIMEPart.
      • Call the SetHeader() method to set the Content-Transfer-Encoding header of the MIME part. Be sure to set this appropriately for the type of data you are sending.
  2. Add the attachments to the web service or web client. To add a given attachment, you insert the MIME part into the appropriate property as follows:
    Each of these properties is a list with the usual list interface (for example, SetAt(), Count(), and GetAt() methods).
  3. Update the appropriate properties of the web client or the web service to describe the attachment contents:
Using Attachments
When a Caché web service or web client receives a SOAP message that has attachments (as specified by the SOAP with Attachments specification), the following happens:
The web service or web client can access these properties and thus access the attachments.
This section provides an example web service and web client that send attachments to each other.
Web Service
The web service provides two methods:
The class definition is as follows:
Class GSOAP.FileTransferWS Extends %SOAP.WebService

///  Name of the web service.
Parameter SERVICENAME = "FileTransfer";

///  SOAP namespace for the web service
Parameter NAMESPACE = "";

/// Namespaces of referenced classes will be used in the WSDL.

///  Receive an attachment and save it
Method UploadAscii(filename As %String = "sample.txt") As %Status [WebMethod]
  //assume 1 attachment; ignore any others
  Set attach=..Attachments.GetAt(1)
  Set file=##class(%FileCharacterStream).%New()
  Set file.Filename="c:\from-client"_$H_filename
  //copy attachment into file
  Set status=file.CopyFrom(attach.Body)
  If $$$ISERR(status) {do $System.Status.DisplayError(status)}
  Set status= file.%Save()        
  Quit status

///  Create an attachment and send it in response to the web client call
Method DownloadBinary(filename As %String = "sample.pdf") As %Status [WebMethod]
  //use a file-type stream to read file contents
  Set file=##class(%Library.FileBinaryStream).%New()
  Set file.Filename="c:\"_filename

  //create MIMEpart and add file to it
  Set mimepart=##class(%Net.MIMEPart).%New() 
  Set mimepart.Body=file

  //set header appropriately for binary file
  Do mimepart.SetHeader("Content-Type","application/octet-stream")
  Do mimepart.SetHeader("Content-Transfer-Encoding","binary")
  Set status=..ResponseAttachments.Insert(mimepart) 
  Quit status

Web Client
The web client application provides two methods:
The generated web client class (GSOAPClient.FileTransfer.FileTransferSoap) includes the methods UploadAscii() and DownloadBinary(), which invoke the corresponding methods of the preceding web service. This class is not shown.
The web client application also includes the following class, which uses this generated web client class:
Include %systemInclude

Class GSOAPClient.FileTransfer.UseClient

ClassMethod DownloadBinary(filename As %String = "sample.pdf") As %Status
  Set client=##class(GSOAPClient.FileTransfer.FileTransferSoap).%New()

  //call web method
  Set ans=client.DownloadBinary(filename)
  //get the attachment (assume only 1)
  Set attach=client.ResponseAttachments.GetAt(1)
  //create a file and copy stream contents into it     
  Set file=##class(%FileBinaryStream).%New()
  //include $H in the filename to make filename unique
  Set file.Filename="c:\from-service"_$H_filename
  Set status=file.CopyFrom(attach.Body)
  If $$$ISERR(status) {do $System.Status.DisplayError(status)}
  Set status= file.%Save()
  Quit status

ClassMethod UploadAscii(filename As %String = "sample.txt") As %Status
  Set client=##class(GSOAPClient.FileTransfer.FileTransferSoap).%New()

  //use a file-type stream to read file contents
  Set file=##class(%Library.FileCharacterStream).%New()
  Set file.Filename="c:\"_filename

  //create MIME part, add file as Body, and set the header
  Set mimepart=##class(%Net.MIMEPart).%New() 
  Set mimepart.Body=file
  Do mimepart.SetHeader("Content-Transfer-Encoding","7bit")
  //attach to client and call web method
  Do client.Attachments.Insert(mimepart)  
  Set status=client.UploadAscii(filename)
  Quit status