Question
· Apr 14, 2023

Simple example of SOAP service to transfer files between systems

I'm trying to create a SOAP service between two systems (one client and one server) to transfer files from the client to the server.

I'm reading through the documentation available at https://docs.intersystems.com/iris20223/csp/docbook/DocBook.UI.Page.cls?... but wanted to look at an actual example of code (preferably a small example for both systems).

If anyone has such an example or could create one, it would greatly help me understand how SOAP services work.

Thank you!

Discussion (1)2
Log in or sign up to continue

Here's a simple example I wrote up and tested based on documentation.

A web service class on the server:

/// Sample.MyService
Class Sample.MyService Extends %SOAP.WebService
{

/// Name of the WebService.
Parameter SERVICENAME = "MyService";

/// TODO: change this to actual SOAP namespace.
/// SOAP Namespace for the WebService
Parameter NAMESPACE = "http://tempuri.org";

/// Namespaces of referenced classes will be used in the WSDL.
Parameter USECLASSNAMESPACES = 1;

Method ReceiveFile(attachment As %GlobalBinaryStream) [ WebMethod ]
{
    set filestream = ##class(%Stream.FileBinary).%New()
    $$$ThrowOnError(filestream.LinkToFile("C:\temp\file_"_$username_$zts_".out"))
    do filestream.CopyFrom(attachment)
    $$$ThrowOnError(filestream.%Save())
}

}

A web client class on the client. This was generated with the SOAP wizard in Studio. Only the datatype of the attachment argument to ReceiveFile has been modified.

Class MyService.Client.MyServiceSoap Extends %SOAP.WebClient [ ProcedureBlock ]
{

/// This is the URL used to access the web service.
Parameter LOCATION = "http://localhost:52773/csp/user/Sample.MyService.cls";

/// This is the namespace used by the Service
Parameter NAMESPACE = "http://tempuri.org";

/// Use xsi:type attribute for literal types.
Parameter OUTPUTTYPEATTRIBUTE = 1;

/// Determines handling of Security header.
Parameter SECURITYIN = "ALLOW";

/// This is the name of the Service
Parameter SERVICENAME = "MyService";

/// This is the SOAP version supported by the service.
Parameter SOAPVERSION = 1.1;

Method ReceiveFile(attachment As %GlobalBinaryStream) [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
 Do (..WebMethod("ReceiveFile")).Invoke($this,"http://tempuri.org/Sample.MyService.ReceiveFile",.attachment)
}

}

And some sample code for the client to use this class to send a file:

/// get the file
set filestream = ##class(%Stream.FileBinary).%New()
$$$ThrowOnError(filestream.LinkToFile(pFileName))

/// create the attachment
set attachment = ##class(%GlobalBinaryStream).%New()
do attachment.CopyFrom(filestream)

/// create the client and send the file
set client = ##class(MyService.Client.MyServiceSoap).%New()
set client.Username = "redacted"
set client.Password = "redacted"
do client.ReceiveFile(attachment)

This will include the entire base-64-encoded file in the body of the SOAP message. An even better way would be to use MTOM attachments for the file. See the documentation here for more details about how to do that: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...