Delphi: WebServices

0

Posted on : 04-06-2012 | By : Paulo H Oliveira | In : Delphi, Internet, Tecnologia

WebServices

Emerson Facunte

Para explicar de maneira adequada o significado da tecnologia WebServices, é interessante fazer uma breve introdução aos problemas atuais no mundo da tecnologia.

Com o grande avanço de sistemas operacionais, bancos de dados, hardware, software, enfim, todo o tipo de tecnologia que envolve o mundo dos negócios, vêm surgindo a necessidade de compartilhamento de informações entre parceiros comerciais, governo e sociedade, e até mesmo entre departamentos de uma empresa.

Acontece que interligar diferentes plataformas, bancos de dados, operações, entre outros conceitos, é uma tarefa muito complicada e trabalhosa.

Para concluir o conceito de WebServices, vamos imaginar um cenário simples, onde precisamos integrar informações de diferentes departamentos e filiais, que foram desenvolvidos em plataformas diferentes. Um bom exemplo para isso, são os bancos que estão adquirindo outros bancos em todo o mundo, e que utilizam conceitos e plataformas diferentes de trabalho.

A figura 1 ilustra o Banco Facunte, adquirindo outros dois bancos com diferentes tecnologias.


figura 1 Banco com diferentes plataformas

Tecnologias do nosso cenário exemplo

Banco S.O. Banco Dados Terminais
Facunte Unix DB2 Terminais Linux
X NT SQL Server Windows
Y Solaris Oracle Terminais Linux

Integrar informações de diferentes plataformas não é novidade, e como já foi mencionado é possível, mas muito trabalhoso. A proposta da tecnologia WebServices neste cenário, é o de facilitar a troca de informações, fazendo o Banco Facunte entender e tratar as informações dos Bancos X e Y, independente do banco de dados, sistema operacional, ou outro fator não citado.

Com algumas linhas de programação e um bom planejamento, as informações essenciais serão interligadas facilmente.

Meus amigos, isso é WebServices!

Em resumo, WebServices, é um padrão não-proprietário, que possibilita o processamento distribuído em sistemas heterogêneos.

E acredito que muitos de vocês neste ponto estão ansiosos para produzir o seu primeiro WebService. Antes, devemos conhecer os padrões que fazem parte da tecnologia.

WebService Exemplo

Vamos criar nosso primeiro WebService para aprender melhor seu conceito.

Através das opções File/New…, seção WebServices, selecione a opção SOAP Server Application (figura 2).


figura 2 Nova aplicação WebService

Em seguida selecione a opção CGI para o tipo da aplicação servidora SOAP (figura 3).


figura 3 Tipo da aplicação servidora


Em seguida o Delphi pergunta se deseja criar uma Interface SOAP padrão (figura 4). Em nosso exemplo, vamos criar a tal Interface, a fim de conhecer sua implementação.



figura 4 Criação da Interface


Em seguida (figura 5) devemos informar os dados da nova Interface.

Nos campos Service Name e Unit identifier coloque wsexemplo. Com isso estamos criando uma Interface com o nome wsexemplo, e gravando a unit com o mesmo nome.

Em Code generation selecione as opções Generate CommentsGenerate Sample Methods. Com isso estamos gerando exemplos de métodos e comentários.


figura 5 Identificação do serviço


Clique em OK para finaliza.

Vamos gravar nossa aplicação.

Unit WebModule un_ws1.pas
Unit Implementação WsExemplo wsexemploImpl.pas
Unit Interface WsExemplo wsexemploIntf.pas
Projeto ws1.dpr


Vamos analisar o que o nosso amigo Delphi criou.


figura 6 WebModule1


A figura 6 ilustra nosso WebModule com três componentes no padrão WebService (HTTPSoapDispatcher, HTTPSoapPascalInvoker,WSDLHTMLPublish).

Vejamos sua implementação.

procedure        TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
       Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  WSDLHTMLPublish1.ServiceInfo(Sender, Request, Response, Handled);
End; 
A única função do nosso WebModule1,é a criação de um handler para o WebService e publicação do documento WSDL.

Na unit wsexemploIntf estamos definindo a Interface de nossa aplicação.
{Invokable interface Iwsexemplo }

unit wsexemploIntf;
interface

uses InvokeRegistry, Types, XSBuiltIns;

type

TEnumTest = (etNone, etAFew, etSome, etAlot);

TDoubleArray = array of Double;

TMyEmployee = class(TRemotable)
private
FLastName: AnsiString;
FFirstName: AnsiString;
FSalary: Double;
published
property LastName: AnsiString read FLastName write FLastName;
property FirstName: AnsiString read FFirstName write FFirstName;
property Salary: Double read FSalary write FSalary;
end;

{ Invokable interfaces must derive from IInvokable }
Iwsexemplo = interface(IInvokable)
['{A391DC0F-CDA7-4929-97B8-DAECA7C2CF18}']

{ Methods of Invokable interface must not use the default }
{ calling convention; stdcall is recommended }
function echoEnum(const Value: TEnumTest): TEnumTest; stdcall;
function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall;
function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall;
function echoDouble(const Value: Double): Double; stdcall;
end;

implementation

initialization
{ Invokable interfaces must be registered }
InvRegistry.RegisterInterface(TypeInfo(Iwsexemplo));

end.

Esta unit na realidade está seguindo as regras da O.O. (Orientação a Objeto), onde definimos uma Interface como base, para que possamos implementar nossas classes. Além disso estamos registrando a Interface no modelo SOAP.

Repare que os métodos criados são apenas exemplos de implementação, que solicitamos previamente, justamente para estudar e analisar.

Na unit wsexemploImpl, temos a implementação da Interface que vimos anteriormente.

Acredito que deu pra perceber, que os métodos apenas retornam os mesmos valores informados.

Para compreender melhor, vamos fazer uma pequena alteração no método echoDouble. Substitua a linha de retorno, pelo código que segue em negrito:

function Twsexemplo.echoDouble(const Value: Double): Double; stdcall;
begin
{ TODO : Implement method echoDouble }
Result := Value * 3;
end;

Perceba que estamos multiplicando por 3, só para quebrar o gelo (Double = Dobro)

Antes de compilar vamos definir o diretório para geração do nosso WebService.

Através das opções Project/Options…/Directories_Conditionals, configure a opção Output Directory, apontando para o o seu diretório cgi-bin (figura 7).


figura 7 Configuração do diretório


Grave novamente a aplicação.

Agora vamos compilar a aplicação.

Vamos executar a aplicação no browser para analisar o seu conteúdo. Lembre-se que para isso você deverá configurar um servidor web, como o Apache, IIS, Xitami, etc.

Digite: http://localhost/cgi-bin/ws1.exe/

figura 8 ilustra o resultado da primeira fase de nossa aplicação.



figura 8 Aplicação ws1


Repare que temos todos os métodos listados na Interface Iwsexemplo (echoEnum, echoDoubleArray, echoMyEmployee, echoDouble).

O documento gerado está de acordo com o padrão estabelecido pelo W3C-UDDI (órgão responsável pelo padrão WebService).

Clicando no link WSDL da Interface Iwexemplo será apresentado um documento WSDL.

Vamos analisar algumas partes do documento para compreender melhor seu funcionamento.

- <types>
- <xs:schema targetNamespace=”urn:wsexemploIntf” xmlns=”urn:wsexemploIntf”>
- <xs:simpleType name=”TEnumTest”>
- <xs:restriction base=”xs:string”>
<xs:enumeration value=”etNone” />
<xs:enumeration value=”etAFew” />
<xs:enumeration value=”etSome” />
<xs:enumeration value=”etAlot” />
</xs:restriction>

Passando pelo bloco das definições inicias (<?xml version=”1.0″…), chegamos no bloco de definições de tipos e métodos.

Neste bloco são definidos todos os métodos da nossa Interface, com o descritivo completo. Repare que a classe TEnumTest é descrita com perfeição.

No bloco que segue, são descritos os métodos Request e Response da Interface em questão.

- <message name=”echoEnum0Request”>
<part name=”Value” type=”ns1:TEnumTest” />
</message>
- <message name=”echoEnum0Response”>
<part name=”return” type=”ns1:TEnumTest” />
</message>

A seguir, temos o bloco que define o nome da porta (Port), e as operações Request e Response, descritas no bloco anterior.

- <portType name=”Iwsexemplo”>
- <operation name=”echoEnum”>
<input message=”tns:echoEnum0Request” />
<output message=”tns:echoEnum0Response” />
</operation>

Em seguida temos o bloco que “envelopa” e define a camada de transporte dos métodos.

- <binding name=”Iwsexemplobinding” type=”tns:Iwsexemplo”>
<soap:binding style=”rpc” transport=”http://schemas.xmlsoap.org/soap/http” />
- <operation name=”echoEnum”>
<soap:operation soapAction=”urn:wsexemploIntf-Iwsexemplo#echoEnum” style=”rpc” />
- <input message=”tns:echoEnum0Request”>
<soap:body use=”encoded” encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”urn:wsexemploIntf-Iwsexemplo” />
</input>
- <output message=”tns:echoEnum0Response”>
<soap:body use=”encoded” encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” namespace=”urn:wsexemploIntf-Iwsexemplo” />
</output>

O último bloco finaliza o documento, declarando o nome do serviço, bem como o nome da porta e a sua camada de transporte.

- <service name=”Iwsexemploservice”>
- <port name=”IwsexemploPort” binding=”tns:Iwsexemplobinding”>
<soap:address location=”http://localhost/delphi/cgi-bin/ws1.exe/soap/Iwsexemplo” />
</port>
</service>
</definitions>

Agora vamos criar uma aplicação cliente para testar nosso primeiro WebService.

Através das opções File/New Application cria uma nova aplicação, e grave os arquivos como segue:

Unit un_teste_ws1.PAS
Projeto teste_ws1.DPR

Agora vamos importar a Interface em nossa aplicação. Através das opções File/New…/WebServices (figura 9), selecione a opção WSDL Importer.


figura 9 WSDL importer

Em seguida, como ilustra a figura 10 , digite endereço que segue.

http://localhost/cgi-bin/ws1.exe/wsdl/Iwsexemplo

Este endereço faz a chamada ao documento WSDL da Interface Iwsexemplo.


figura 10 Importação da Interface através do WSDL

Este procedimento está importando toda a Interface para a nossa aplicação. Com isso teremos acesso aos métodos definidos.

É interessante destacar que um WebService poderá ter inúmeras Interfaces, onde poderemos importar apenas as que condizem com a nossa necessidade.

Aperte o botão Next para avançar a avançar à próxima fase.

A figura 11 ilustra a Interface gerada pelo assistente.



figura 11 Interface gerada pelo assistente


Para concluir aperte a tecla Finish.

O assistente gerou uma Unit com toda a Interface implementada.

Grave a Unit com o nome Iwsexemplo1.pas.

O que acabamos de fazer, na realidade, foi a importação de uma Interface para facilitar o uso do WebService.

Agora com o foco na unit un_teste_ws1, insira a unit Iwexemplo1.pas gerada pelo assistente.

implementation
       uses Iwsexemplo1;


Neste ponto iremos configurar o acesso para este formulário.

Insira um objeto do tipo THTTPRIO, e configure as propriedades que seguem, respeitando a seqüência apresentada, caso contrário, uma exceção ocorrerá.

OBJETO
THTTPRio
Objeto Propriedade Valor
HTTPRio1 Name HR1
WSDLLocation http://localhost/cgi-bin/ ws1.exe/wsdl/Iwsexemplo
Service Iwsexemploservice
Port IwsexemploPort

Com isto configuramos o objeto de acesso à Interface, informando a localização do documento WSDL (WSDLLocation), o serviço (Service), e a porta (Port).

Agora insira os objetos que seguem, configurando suas respectivas propriedades.

OBJETO
TEdit
Objeto Propriedade Valor
edValor Name edValor
Left 32
Text deixe em branco
Top 24
Width 120
OBJETO
TButton
Objeto Propriedade Valor
Button1 Name Button1
Caption Calcula
Left 176
Top 24
Width 125
OBJETO
Tlabel
Objeto Propriedade Valor
lbResultado Name lbResultado
Caption 0
Left 32
Top 64


A figura 12 ilustra o formulário da nossa aplicação.


figura 12 Formulário da aplicação


Agora vamos codificar a aplicação. Insira o código que segue no evento OnClick do objeto Button1.

var
Iexemplo: Iwsexemplo;
begin
Iexemplo:= HR1 as Iwsexemplo;
lbResultado.Caption:=FloattoStr(Iexemplo.echoDouble( StrtoFloat(edValor.Text)));
end;

O código é bastante simples, onde estamos definindo um objeto do tipo Iwsexemplo. Em seguida estamos instanciando o objeto a partir do nosso HTTPRio (HR1), adotando o modelo Iwsexemplo. E por fim, apresentamos o resultado em nosso objeto lbResultado, através da função IExemplo.echoDouble.

O mais importante até aqui, é justamente a compreensão de como conseguimos implementar o WebService em nossa aplicação.

Vamos testar nossa aplicação.

Compile e execute a aplicação, informando um número no campo e pressionando o botão. A figura 13 ilustra nossa aplicação em tempo de execução.


figura 13 Aplicação em tempo de execução


Perceba que a primeira vez que pressionamos o botão, existe um delay, que é justamente o tempo de conexão com o WebService.

Repita a operação, e repare que já não existe mais o delay.

Amigos isto é apenas o começo. Em meu livro Delphi 7 Internet e Banco de Dados, explico através de exemplos práticos todo o poder dos WebServices. Temos WebServices utilizando banco de dados como serviço, e também conexões concorrentes utilizando o protocolo SOAP.

Forte abraço e imenso sucesso a todos !!!


EMERSON FACUNTE

Compartilhe :

  • Stumble upon
  • twitter

Escreva um comentário

Security Code: