SOAP: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added C implementation.)
Line 36: Line 36:
#Include ws4ahk.ahk ; http://www.autohotkey.net/~easycom/ws4ahk_public_api.html</lang>
#Include ws4ahk.ahk ; http://www.autohotkey.net/~easycom/ws4ahk_public_api.html</lang>


=={{header|C}}==
Although this is a generic task to show that calling SOAP functions are possible, the following implementation is geared for the real world. In order to execute it, just choose an actual WSDL URL and construct the input XML files for the functions properly, this can also be done in C but requires libraries like xerces unless you want to really construct the XML from scratch.
{{libheader|libcurl}}
<lang C>
/*Abhishek Ghosh, 26th October 2017*/

#include <curl/curl.h>
#include <string.h>
#include <stdio.h>

size_t write_data(void *ptr, size_t size, size_t nmeb, void *stream){
return fwrite(ptr,size,nmeb,stream);
}

size_t read_data(void *ptr, size_t size, size_t nmeb, void *stream){
return fread(ptr,size,nmeb,stream);
}

void callSOAP(char* URL, char * inFile, char * outFile) {

FILE * rfp = fopen(inFile, "r");
if(!rfp)
perror("Read File Open:");

FILE * wfp = fopen(outFile, "w+");
if(!wfp)
perror("Write File Open:");

struct curl_slist *header = NULL;
header = curl_slist_append (header, "Content-Type:text/xml");
header = curl_slist_append (header, "SOAPAction: rsc");
header = curl_slist_append (header, "Transfer-Encoding: chunked");
header = curl_slist_append (header, "Expect:");
CURL *curl;

curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, URL);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_data);
curl_easy_setopt(curl, CURLOPT_READDATA, rfp);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, wfp);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)-1);
curl_easy_setopt(curl, CURLOPT_VERBOSE,1L);
curl_easy_perform(curl);

curl_easy_cleanup(curl);
}
}

int main(int argC,char* argV[])
{
if(argC!=4)
printf("Usage : %s <URL of WSDL> <Input file path> <Output File Path>",argV[0]);
else
callSOAP(argV[1],argV[2],argV[3]);
return 0;
}
</lang>
Input XML for soapFunc()
<lang XML>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dom="http://example.com/soap/wsdl">
<soapenv:Header/>
<soapenv:Body>
<dom:soapFunc soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>
</soapenv:Envelope>
</lang>
Input XML for anotherSoapFunc()
<lang XML>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dom="http://example.com/soap/wsdl">
<soapenv:Header/>
<soapenv:Body>
<dom:anotherSoapFunc soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>
</soapenv:Envelope>
</lang>
=={{header|ColdFusion}}==
=={{header|ColdFusion}}==
<lang cfm><cfset client = createObject("webservice","http://example.com/soap/wsdl")>
<lang cfm><cfset client = createObject("webservice","http://example.com/soap/wsdl")>
<cfset result = client.soapFunc("hello")>
<cfset result = client.soapFunc("hello")>
<cfset result = client.anotherSoapFunc(34234)></lang>
<cfset result = client.anotherSoapFunc(34234)></lang>



=={{header|F Sharp|F#}}==
=={{header|F Sharp|F#}}==

Revision as of 13:51, 26 October 2017

Task
SOAP
You are encouraged to solve this task according to the task description, using any language you may know.

In this task, the goal is to create a SOAP client which accesses functions defined at http://example.com/soap/wsdl, and calls the functions soapFunc( ) and anotherSoapFunc( ).

This task has been flagged for clarification. Code on this page in its current state may be flagged incorrect once this task has been clarified. See this page's Talk page for discussion.


ActionScript

Works with: ActionScript version 3.0

<lang actionscript>import mx.rpc.soap.WebService; import mx.rpc.events.ResultEvent; var ws:WebService = new WebService(); ws.wsdl = 'http://example.com/soap/wsdl'; ws.soapFunc.addEventListener("result",soapFunc_Result); ws.anotherSoapFunc.addEventListener("result",anotherSoapFunc_Result); ws.loadWSDL(); ws.soapFunc(); ws.anotherSoapFunc(); // method invocation callback handlers private function soapFunc_Result(event:ResultEvent):void {

 // do something

} private function anotherSoapFunc_Result(event:ResultEvent):void {

 // do another something

}</lang>

AutoHotkey

using embedded vb scripting.

Library: ws4ahk

<lang AutoHotkey>WS_Initialize()

   WS_Exec("Set client = CreateObject(""MSSOAP.SoapClient"")")
   WS_Exec("client.MSSoapInit ""http://example.com/soap/wsdl""")
   callhello = client.soapFunc("hello")
   callanother = client.anotherSoapFunc(34234)
   
   WS_Eval(result, callhello)
   WS_Eval(result2, callanother)
   Msgbox % result . "`n" . result2
   WS_Uninitialize()
  1. Include ws4ahk.ahk  ; http://www.autohotkey.net/~easycom/ws4ahk_public_api.html</lang>

C

Although this is a generic task to show that calling SOAP functions are possible, the following implementation is geared for the real world. In order to execute it, just choose an actual WSDL URL and construct the input XML files for the functions properly, this can also be done in C but requires libraries like xerces unless you want to really construct the XML from scratch.

Library: libcurl

<lang C> /*Abhishek Ghosh, 26th October 2017*/

  1. include <curl/curl.h>
  2. include <string.h>
  3. include <stdio.h>

size_t write_data(void *ptr, size_t size, size_t nmeb, void *stream){

   return fwrite(ptr,size,nmeb,stream);

}

size_t read_data(void *ptr, size_t size, size_t nmeb, void *stream){

   return fread(ptr,size,nmeb,stream);

}

void callSOAP(char* URL, char * inFile, char * outFile) {

   FILE * rfp = fopen(inFile, "r");
   if(!rfp) 
       perror("Read File Open:");
   FILE * wfp = fopen(outFile, "w+");
   if(!wfp)
       perror("Write File Open:");
   struct curl_slist *header = NULL;

header = curl_slist_append (header, "Content-Type:text/xml"); header = curl_slist_append (header, "SOAPAction: rsc"); header = curl_slist_append (header, "Transfer-Encoding: chunked"); header = curl_slist_append (header, "Expect:");

   CURL *curl;
   curl = curl_easy_init();
   if(curl) {
       curl_easy_setopt(curl, CURLOPT_URL, URL);
       curl_easy_setopt(curl, CURLOPT_POST, 1L);
       curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_data);
       curl_easy_setopt(curl, CURLOPT_READDATA, rfp); 
       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
       curl_easy_setopt(curl, CURLOPT_WRITEDATA, wfp);
       curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);
       curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)-1);
       curl_easy_setopt(curl, CURLOPT_VERBOSE,1L);            
       curl_easy_perform(curl);
       curl_easy_cleanup(curl);
   }

}

int main(int argC,char* argV[]) { if(argC!=4) printf("Usage : %s <URL of WSDL> <Input file path> <Output File Path>",argV[0]); else callSOAP(argV[1],argV[2],argV[3]); return 0; } </lang> Input XML for soapFunc() <lang XML> <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dom="http://example.com/soap/wsdl">

  <soapenv:Header/>
  <soapenv:Body>
     <dom:soapFunc soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </soapenv:Body>

</soapenv:Envelope> </lang> Input XML for anotherSoapFunc() <lang XML> <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dom="http://example.com/soap/wsdl">

  <soapenv:Header/>
  <soapenv:Body>
     <dom:anotherSoapFunc soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </soapenv:Body>

</soapenv:Envelope> </lang>

ColdFusion

<lang cfm><cfset client = createObject("webservice","http://example.com/soap/wsdl")> <cfset result = client.soapFunc("hello")> <cfset result = client.anotherSoapFunc(34234)></lang>

F#

The availability of functions and the type of parameters is checked at compile time. The development environment supports auto-completion and parameter information just like for regular types.

<lang fsharp>open Microsoft.FSharp.Data.TypeProviders

type Wsdl = WsdlService<"http://example.com/soap/wsdl"> let result = Wsdl.soapFunc("hello") let result2 = Wsdl.anotherSoapFunc(34234)</lang>

Icon and Unicon

provides the Soap package.

This code uses Unicon features not available in Icon. <lang unicon>import soap

procedure main(A)

   soap := SoapClient(A[1] | "http://example.com/soap/wsdl")  # Allow override of default
   write("soapFunc: ",soap.call("soapFunc"))
   write("anotherSoapFunc: ",soap.call("anotherSoapFunc"))

end</lang>

A matching SOAP server can be implemented as:

<lang unicon>import soap

procedure main()

   server := SoapServer("http://example.com/soap/wsdl")
   server.addService("soapFunc",   soapFunc)
   server.addService("anotherSoapFunc", anotherSoapFunc)
   msg := server.handleRequest()
   write(msg)
   exit(0)

end

procedure soapFunc(A[])

   every (s := " ") ||:= (!A || " ")
   return "Hello" || s[1:-1]

end

procedure anotherSoapFunc(A[])

   every (s := " ") ||:= (!A || " ")
   return "Goodbye" || s[1:-1]

end</lang>

Mathematica

<lang Mathematica>InstallService["http://example.com/soap/wsdl"]; soapFunc["Hello"]; anotherSoapFunc[12345]; </lang>


Perl

<lang perl>use SOAP::Lite;

print SOAP::Lite

 -> service('http://example.com/soap/wsdl')
 -> soapFunc("hello");

print SOAP::Lite

 -> service('http://example.com/soap/wsdl')
 -> anotherSoapFunc(34234);</lang>

PHP

Works with: PHP version 5.0.0+

<lang php><?php //load the wsdl file $client = new SoapClient("http://example.com/soap/definition.wsdl"); //functions are now available to be called $result = $client->soapFunc("hello"); $result = $client->anotherSoapFunc(34234);

//SOAP Information $client = new SoapClient("http://example.com/soap/definition.wsdl"); //list of SOAP types print_r($client->__getTypes()); //list if SOAP Functions print_r($client->__getFunctions()); ?></lang>

PureBasic

<lang Purebasic> XIncludeFile "COMatePLUS.pbi" Define.COMateObject soapObject = COMate_CreateObject("MSSOAP.SoapClient") soapObject\Invoke("MSSoapInit('http://example.com/soap/wsdl')") result = soapObject\Invoke("soapFunc('hello')") result2 = soapObject\Invoke("anotherSoapFunc(34234)") </lang>

Python

Works with: Python version 2.4 and 2.5

<lang python>from SOAPpy import WSDL proxy = WSDL.Proxy("http://example.com/soap/wsdl") result = proxy.soapFunc("hello") result = proxy.anotherSoapFunc(34234)</lang>

Note: SOAPpy is a third-party module and can be found at Python Web Services

Ruby

Works with: Ruby version 1.8

<lang ruby>require 'soap/wsdlDriver'

wsdl = SOAP::WSDLDriverFactory.new("http://example.com/soap/wsdl") soap = wsdl.create_rpc_driver

response1 = soap.soapFunc(:elementName => "value") puts response1.soapFuncReturn

response2 = soap.anotherSoapFunc(:aNumber => 42) puts response2.anotherSoapFuncReturn</lang>

Smalltalk

Works with: Smalltalk/X
Works with: Dolphin Smalltalk

(not sure about Pharo and VW)

(assuming that the open source SOAPSpray package has been loaded.) <lang smalltalk>| service client response1 response2 |

service := SprayWSDLService onUrl: 'http://example.com/soap/wsdl'.

client := service createClient. response1 := client send: 'soapFunc' withArguments:{ 'hello' }. response2 := client send: 'anotherSoapFunc' withArguments:{ 34234 }.</lang>

Tcl

Works with: Tcl version 8.5+

Uses the tclws package. <lang Tcl>package require WS::Client

  1. Grok the service, and generate stubs
WS::Client::GetAndParseWsdl http://example.com/soap/wsdl
WS::Client::CreateStubs ExampleService  ;# Assume that's the service name...
  1. Do the calls

set result1 [ExampleService::soapFunc "hello"] set result2 [ExampleService::anotherSoapFunc 34234]</lang>


Uniface

Assuming http://example.com/soap/wsdl has been imported into repository and, as result, exists a new component called "webservice"

<lang Uniface> variables

  string result1, result2

endvariables

activate "webservice".soapFunc("hello", result1) activate "webservice".anotherSoapFunc(34234, result2) </lang>

VBScript

<lang vbscript>Dim client Dim result Set client = CreateObject("MSSOAP.SoapClient") client.MSSoapInit "http://example.com/soap/wsdl" result = client.soapFunc("hello") result = client.anotherSoapFunc(34234)</lang>

Visual Objects

<lang visobj>LOCAL oSoapClient AS OLEAUTOOBJECT LOCAL cUrl AS STRING LOCAL uResult AS USUAL oSoapClient := OLEAutoObject{"MSSOAP.SoapClient30"} cUrl  := "http://example.com/soap/wsdl" IF oSoapClient:fInit

  oSoapClient:mssoapinit(cUrl,"", "", "" )
  uResult := oSoapClient:soapFunc("hello")
  uResult := oSoapClient:anotherSoapFunc(34234)

ENDIF</lang>