De todas as soluções possíveis que estive a ver, a melhor foi usar Python.
Encontrei este exemplo:
http://users.skynet.be/pascalbotte/rcx-ws-doc/postxmlpython.htm
Assim fiz o WebServiceGenericClientNet.py:
#!/usr/bin/python
# by eduveks
import sys, httplib, array
try:
host = ""
url = ""
namespace = ""
header = ""
method = ""
params = {}
for arg in sys.argv[1:]:
if host == "" and arg.find("host=") == 0:
host = arg[len("host="):]
elif url == "" and arg.find("url=") == 0:
url = arg[len("url="):]
elif namespace == "" and arg.find("namespace=") == 0:
namespace = arg[len("namespace="):]
elif header == "" and arg.find("header=") == 0:
header = arg[len("header="):]
elif method == "" and arg.find("method=") == 0:
method = arg[len("method="):]
elif arg.find("param_") == 0:
params[arg[len("param_"):arg.find("=")]] = arg[arg.find("=") + 1:]
SOAP_Request = ""
SOAP_Request += "<soap:Envelope"
SOAP_Request += " soap:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
SOAP_Request += " xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\""
SOAP_Request += " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""
SOAP_Request += " xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\">"
if header != "": SOAP_Request += "<soap:Header>" SOAP_Request += header SOAP_Request += "</soap:Header>" SOAP_Request += "<soap:Body>"
SOAP_Request += "<"+ method +" xmlns=\""+ namespace +"\">"
for param in params.keys():
SOAP_Request += "<"+ param +">"+ params[param] +"</"+ param +">"
SOAP_Request += "</"+ method +">"
SOAP_Request += "</soap:Body>"
SOAP_Request += "</soap:Envelope>"
http = httplib.HTTP(host)
http.putrequest("POST", url)
http.putheader("Host", host)
http.putheader("User-Agent", "Python")
http.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
http.putheader("Content-length", "%d" % len(SOAP_Request))
http.putheader("SOAPAction", "\""+ namespace + method +"\"")
http.endheaders()
http.send(SOAP_Request)
http_response_statuscode, http_response_statusmessage, http_response_header = http.getreply()
SOAP_Response = http.getfile().read()
if http_response_statuscode == 200 and http_response_statusmessage == "OK":
print SOAP_Response[SOAP_Response.find("<"+ method +"Result>") + len("<"+ method +"Result>"):SOAP_Response.find("</"+ method +"Result>")]
else:
print "### ERROR ###############"
if SOAP_Response.find("<faultstring>") > -1:
print SOAP_Response[SOAP_Response.find("<faultstring>") + len("<faultstring>"):SOAP_Response.find("</faultstring>")]
print "Response: ", http_response_statuscode, http_response_statusmessage
print http_response_header
print SOAP_Response
except:
print "### ERROR ###############"
for err in sys.exc_info():
print err
Para executar o script basta dar permissões de execução e executar:
chmod +x WebServiceGenericClientNet.py
./WebServiceGenericClientNet.py host=localhost url=/HelloWorld.asmx namespace=http://tempuri.org/ method=HelloWorld param_strSay=HelloWorld
O output é:
HelloWorld
Os parâmetros do WebServiceGenericClientNet.py são:
host: Endereço do servidor
url: Endereço do web service
namespace: Namespace do web service, que pode ser encontrado vendo o WSDL, http://localhost/HelloWorld.asmx?WSDL
method: Método do web service a ser chamado
param_*NOME_DO_PARAMETRO*: Caso o método precise de parâmetros, podem ser definidos assim, atenção a ordem.
Além de usar este script no Solaris, também acabei por usar este script para chamar web services apartir do .Net/C#, pois são web services que serão atualizados constantemente, com novos métodos e talz, e em vez de ficar atualizando o WSDL, basta chamar diretamente com o script a queima-roupa, e a configuração da chamada dos web services pode ser feita a partir de configurações em base de dados. Para fazer isto no .Net/C# foi só lançar um processo assim:
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = "C:\Python26\python.exe";
process.StartInfo.Arguments = "WebServiceGenericClientNet.py host=localhost url=/HelloWorld.asmx namespace=http://tempuri.org/ method=HelloWorld param_strSay=HelloWorld";
process.StartInfo.WorkingDirectory = "C:\Python26\";
process.Start();
string output = process.StandardOutput.ReadToEnd();
O script suporta a configuração do header, passando o argumento header=... para o script.
Para explorar e ver fácilmente os SOAPs enviados e recebidos na chamada de um web service, existe o WebServiceStudio: