Repository navigation
modulo soap
Home > Servidor SOAP
Important
Em desenvolvimento (2.0). Ainda não está numa versão lançada e pode mudar.
Nível: intermediário
Em uma frase: o TRALSOAPModule transforma o seu servidor RAL num serviço
SOAP 1.1 e 1.2: cada operação é um item de uma lista, o WSDL sai sozinho e as
falhas viram Fault no formato que cada versão pede.
Você vai precisar: RAL 2.0 com os pacotes RALModuleXMLPackage e
RALModuleSOAPPackage instalados (Instalação). Funciona em todos os
motores de servidor.
- Coloque um
TRALSOAPModule(paleta RAL - Modules) no formulário ou data module do servidor e ligueServerao seu servidor. - Preencha
Domain(o endereço do serviço, por exemplo/calc),Namespace(por exemplourn:calc) eServiceName(o nome no WSDL). - Abra
Operationse adicione um item por operação. Em cada um:-
Name: o nome da operação (Somar); -
InputParamseOutputParams: os valores de entrada e de saída, comParamName,ParamTypeeRequired- é deles que o WSDL é gerado; - dois cliques em
OnExecutepara escrever o tratador.
-
- Ligue o servidor. O WSDL está em
http://servidor:porta/calc?wsdl(qualquerGETno endereço do serviço responde o WSDL).
O tratador recebe o pedido e a resposta do SOAP:
procedure TForm1.SomarExecute(ARequest: TRALSOAPRequest; AResponse: TRALSOAPResponse);
var
vA, vB: Integer;
begin
vA := StrToInt(ARequest.ParamValue('a'));
vB := StrToInt(ARequest.ParamValue('b'));
AResponse.AddResult('SomarResult').WithValue(Int64(vA + vB));
end;O cliente manda:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body><Somar xmlns="urn:calc"><a>2</a><b>3</b></Somar></soap:Body>
</soap:Envelope>e recebe <SomarResponse xmlns="urn:calc"><SomarResult>5</SomarResult></SomarResponse>
dentro do Body.
Em vez de OnExecute, ligue ResultDataSet da operação a uma query do
formulário: o módulo abre a query e responde as linhas dentro do Body, no
formato de ResultXMLType (os formatos estão em Storage XML).
Um POST no endereço do serviço é atendido pela operação que o pedido nomeia,
nesta ordem:
- o
SOAPAction(SOAP 1.1, cabeçalho) ou oactiondoContent-Type(SOAP 1.2) - igual aoSOAPActionda operação, ou aoNamespaceseguido doNamequando ele está vazio; - o nome do primeiro elemento do
Body.
Cada operação também responde em Domain/Name (/calc/Somar).
O módulo só lê o começo do envelope para escolher a operação, antes da autenticação: um pedido recusado nunca chega a ter o envelope inteiro montado.
TRALSOAPRequest |
O que é |
|---|---|
ParamValue(nome, padrão) |
texto do filho nome do elemento da operação (ou do parâmetro de URL de mesmo nome) |
Param(nome) |
o nó do filho nome, para ler valores tipados (AsInteger, AsDateTime, AsBCD...) |
Payload |
o elemento da operação, inteiro |
SOAPHeader, SOAPBody, Envelope, Document
|
as partes do envelope (XML) |
Version, Action, Operation
|
versão, ação e operação do pedido |
TRALSOAPResponse |
O que faz |
|---|---|
AddResult(nome) |
acrescenta um valor ao elemento <Operacao>Response e devolve o nó, para encadear WithText, WithValue... |
Payload |
o elemento <Operacao>Response, para montar o que quiser |
Answer(dataset, formato) |
responde um dataset |
Answer(nó), AnswerXML(texto)
|
põe um XML pronto no Body
|
AddHeaderBlock(nome, namespace) |
acrescenta um bloco ao Header da resposta |
AnswerFault(código, motivo, detalhe) |
responde uma falha |
A resposta sai na mesma versão do pedido.
- Uma exceção dentro do tratador vira
Faultcom códigoReceiver(soap:Serverna 1.1) e a mensagem da exceção. ComHideErrorDetailsdo servidor, a mensagem vira só "Internal Server Error". -
raise ERALSOAPFault.CreateFault(sfcSender, 'motivo', '<detalhe/>')ouAResponse.AnswerFault(...)respondem a falha que você quiser. - O status HTTP segue a norma: na 1.1 toda falha é
500; na 1.2Senderé400e as outras500. - Um bloco do
HeadermarcadomustUnderstandque a operação não processa respondeMustUnderstand. Liste emHeadersda operação os blocos que ela trata.
O padrão é o da norma: text/xml na 1.1 e application/soap+xml na 1.2.
Para um parceiro que só aceita outro tipo, troque EnvelopeContentType (por
exemplo application/xml). ContentType é o tipo das respostas do módulo que
não são envelope (padrão application/xml) e WSDLContentType o do WSDL
(padrão text/xml).
| Propriedade | O que faz |
|---|---|
Domain |
endereço do serviço |
Namespace |
namespace do serviço e das operações sem um próprio (padrão urn:ral-service) |
ServiceName |
nome do serviço no WSDL (padrão RALService) |
ServiceURL |
endereço do serviço escrito no WSDL; vazio usa o do pedido |
Versions |
versões aceitas (padrão 1.1 e 1.2); outra responde VersionMismatch
|
WSDLFile |
serve este arquivo como WSDL em vez do gerado |
WSDLRequireAuth |
True: o WSDL também pede o login do servidor (padrão: livre) |
ReaderOptions |
limites do leitor para os envelopes que chegam (XML) |
EnvelopeContentType, ContentType, WSDLContentType
|
ver acima |
Cada operação (Operations): Name, Namespace, SOAPAction, Style
(ssDocument - document/literal wrapped, o padrão - ou ssRPC - rpc/literal),
Headers, InputParams, OutputParams, ResultDataSet, ResultXMLType e
OnExecute.
Clique com o botão direito no componente e escolha Exportar WSDL... para
salvar o arquivo. Em código: RALSOAPModule1.GenerateWSDL('http://host/calc').
O WSDL é 1.1, com um binding para cada versão aceita. Operações document e rpc
no mesmo módulo ganham um portType e um binding para cada estilo
(ServiceNameSoap e ServiceNameRpcSoap), como o WS-I Basic Profile pede -
o wsimport do Java recusa um binding que mistura os dois.
O WSDL gerado foi importado, e o serviço chamado, por:
| Cliente | Como |
|---|---|
Delphi (THTTPRIO) |
WSDLImp gera as interfaces; document vira Add(a, b): Int64, rpc também |
| .NET Framework |
New-WebServiceProxy / SoapHttpClientProtocol, SOAP 1.1 e 1.2 |
| Java (JAX-WS) |
wsimport do JDK 8 |
Com operações dos dois estilos no mesmo serviço, o wsimport do JDK 8 marca o
método rpc com uma anotação que contradiz o próprio estilo e a chamada falha
ao montar o proxy; com o serviço todo document ou todo rpc ele funciona. Se o
parceiro for Java, prefira um estilo só por módulo.
O texto que chega pode estar em qualquer codificação que o leitor
conhece: o charset do Content-Type, quando o cliente manda um, vale; sem
ele, a BOM ou a declaração encoding do XML decidem.
O envelope é lido com os limites de ReaderOptions (profundidade, atributos,
expansão de entidades). Um envelope com DOCTYPE ou instrução de
processamento é recusado sempre (a norma do SOAP 1.2 proíbe), o que fecha as
bombas de entidades e o XXE. Ver Segurança para produção.
uses RALSOAPTypes, RALSOAPModule;
Modulo := TRALSOAPModule.Create(nil);
Modulo.Domain := '/calc';
Modulo.Namespace := 'urn:calc';
Op := Modulo.AddOperation('Somar', SomarExecute, 'Soma dois inteiros');
// InputParams/OutputParams documentam a operação no WSDL
Modulo.Server := Servidor;
Servidor.Active := True;Começar
Servidor
- Rotas e parâmetros
- Ler o pedido e responder
- Plugins 🚧
- Autenticação
- Banco de dados (DBWare)
- Servir site e arquivos
- Swagger e Postman
- Servidor SOAP 🚧
- HTTPS
- Criptografia ponto a ponto
- Segurança para produção
- Colocar no ar
- Desempenho
Cliente
Motores
Avançado
Ajuda
- Problemas comuns
- Atualizar o Indy
- Várias versões do Delphi
- Vídeos e guias
- Módulos de terceiros
- Licenças
- Contribuir
- Roadmap e changelog
🚧 = em desenvolvimento, pode mudar