Você está na página 1de 3

:: Active Delphi

http://www.activedelphi.com.br/print.php?sid=1569

Delphi http://www.activedelphi.com.br/print.php?sid=1569 [Intermediário] -Recuperando o XML de uma requisição SOAP

[Intermediário] -Recuperando o XML de uma requisição SOAP em Delphi

Data: Thursday, March 20 @ 13:47:02 Tópico Diego Garcia

Talvez a maneira mais popular de se fazer uma integração entre diferentes aplicações é através de Webservices SOAP. Inúmeras aplicações governamentais trabalham com webservices, como é o caso do projeto Farmácia Popular, Nota Fiscal Eletrônica (NFe),Conhecimento de Transporte Eletrônico (CTe), etc.

Para ajudar nesse processo, existem as definições WSDL que consiste numa espécie de documentação do webservice. Para ficar ainda melhor, o Delphi está preparado para importar as definições WSDL de um webservice e já criar toda uma interface de comunicação entre a sua aplicação e o webservice, sendo necessário somente consumir os métodos já criados. Obviamente existe um mundo de definições e pequenos detalhes que não irei me aprofundar.

Para mostrar o quanto tudo isso é tranquilo, faremos o processo completo para o consumo de um webservice simples. O site WebserviceX.NET (http://webservicex.net/ws/default.aspx) possui uma série de webservices livres para testes. Usaremos o webservice Currency Convertor, um webservice responsável por obter taxa de conversão de uma moeda para outra.

Importando o WSDL Primeiramente (após criar um novo projeto obviamente) iremos importar o arquivo WSDL do webservice Currency Convertor. Esse está disponível no endereço: http://www.webservicex.net/CurrencyConvertor.asmx?WSDL. Baixe esse arquivo na sua máquina e vamos ao processo de importação no Delphi. Com o projeto criado, vá em File -> New Other e depois vá em Webservices -> WSDL Importer

New Other e depois vá em Webservices -> WSDL Importer O processo de importar o WSDL

O processo de importar o WSDL é extremamente simples, next -> next -> finish (não se preocupe com as opções, faça a importação com a parametrização default). Após a importação, será criada a unit CurrencyConvertor.pas e essa já será adicionada ao projeto.

Consumindo o Webservice

:: Active Delphi

http://www.activedelphi.com.br/print.php?sid=1569

Com isso seu aplicativo já está praticamente pronto para consumir o webservice, bastando apenas incluir um código extremamente simples (obviamente, pelo fato do webservice ser simples).

uses

CurrencyConvertor

procedure TfrmWebserviceCliente.Converter();

var

oCCSoap : CurrencyConvertorSoap;

begin

oCCSoap := GetCurrencyConvertorSoap();

try

ShowMessageFmt('USD -> BRL = $%f',[oCCSoap.ConversionRate(Currency.USD,Currency.BRL)]);

finally

oCCSoap := nil;

end;

end;

Se você nunca consumiu um webservice antes e está acompanhando esse post, parabens, você acaba de consumir o seu primeiro webservice :). No código acima foi convertido o valor de 1 dolar para real.

Para saber qual método você deve executar para criar uma instancia do objeto que representa o webservice, na unit que foi gerada pela importação do WSDL, basta conferir os métodos da sessão implementation, o Delphi sempre disponibilizar um método com a assinatura Get[NomeDoWebservice].

Recuperando o conteúdo das mensagens.

O grande problema de tudo isso é que essa negociação HTTP toda, fica muito camuflada dentro das implementações do Delphi e

por algumas vezes, tive a necessidade de validar o conteúdo XML puro da requisição assim como o XML puro de resposta. Para resolver esse problema, basta utilizar um componente THttpRIO e interceptar o conteúdo da negociação HTTP. Calma, não se assuste, isso é bem simples.

O componente THttpRio, dentre outras coisas, possui os métodos OnBeforeExecute eOnAfterExecute, o primeiro é executado

antes da requisição e o segundo após momento da resposta. Em nosso exemplo, adicione esse componente e mais dois TMemo em seu projeto (mmRequest e mmResponse) e defina os métodos OnBeforeExecute e OnAfterExecute do componente THttpRio da seguinte maneira.

procedure TfrmWebserviceCliente.httpRioBeforeExecute(const MethodName: string; SOAPRequest: TStream);

begin

SOAPRequest.Position := 0;

mmRequest.Lines.LoadFromStream(SOAPRequest); SOAPRequest.Position := 0;

end;

procedure TfrmWebserviceCliente.httpRioAfterExecute(const MethodName: string; SOAPResponse: TStream);

begin

SOAPResponse.Position := 0; mmResponse.Lines.LoadFromStream(SOAPResponse); SOAPResponse.Position := 0;

end;

Esse foi apenas um exemplo simplório, mas como você pode ver, tanto o conteúdo do request (SOAPRequest), quanto o conteúdo

do response (SOAPResponse) são objetos do tipo TStream, sendo assim, você pode manipular essa informação da maneira que for necessária, inclusive, se necessário, é possível manipular o request para que o conteúdo enviado não seja o gerado pelo Delphi

e sim, um conteúdo gerado em outra rotina. Para realizarmos o teste, vamos mudar a criação da instancia do objeto que representa o webservice, para que ele tenha conhecimento do nosso componente THttpRio.

procedure TfrmWebserviceCliente.Converter;

var

oCCSoap : CurrencyConvertorSoap;

begin

oCCSoap := GetCurrencyConvertorSoap(false, EmptyStr, httpRio);

try

ShowMessageFmt('USD -> BRL = $%f',[oCCSoap.ConversionRate(Currency.USD,Currency.BRL)]);

finally

oCCSoap := nil;

end;

end;

Veja que agora estamos especificando 3 parâmetros, o primeiro é se nossa instancia do webservice irá utilizar o endereço do

:: Active Delphi

http://www.activedelphi.com.br/print.php?sid=1569

WSDL como endereço do serviço, o segundo parâmetro define qual será o endereço final da requisição (note que o segundo parâmetro anula o primeiro) e por fim, o terceiro parâmetro é o componente THttpRio.

Feita a alteração, repita o teste e veja que em nossos componentes memos, estão os conteúdos de request e response da requisição, conforme a especificado a baixo.

Request:

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org /2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <ConversionRate xmlns="http://www.webserviceX.NET/"> <FromCurrency>USD</FromCurrency> <ToCurrency>BRL</ToCurrency> </ConversionRate> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Response:

<?xml version="1.0" encoding="UTF-8"?>

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soap:Body> <ConversionRateResponse xmlns="http://www.webserviceX.NET/">

<ConversionRateResult>2.349</ConversionRateResult>

</ConversionRateResponse>

</soap:Body>

</soap:Envelope>

Acredite, é realmente muito útil ter em mãos o conteúdo da requisição, pois é comum que em um cenário de integração entre aplicações, o fornecedor do serviço, solicite opayload da requisição, ou seja, o conteúdo desta, para validar possíveis inconsistência.

Disponibilizei no Gist (https://gist.github.com/drgarcia1986/9610291) os fontes completos de um projeto utilizando esses códigos de exemplo, com algumas pequenas modificações (crio o THttpRio de forma dinâmica, fiz combos com as possíveis moedas, etc.), quem tiver interesse é só baixar e montar o projeto.

Diego Garcia

http://drgarcia1986.wordpress.com

http://twitter.com/drgarcia1986

https://github.com/drgarcia1986

Digitado por :: Active Delphi http://www.activedelphi.com.br/

A URL para esta notícia é:

http://www.activedelphi.com.br/modules.php?op=modload&name=News&file=article&sid=1569