domingo, 20 de fevereiro de 2011

Como consumir WebServices em Delphi

Como consumir WebServices em Delphi

E ai pessoal , tudo bem? Espero que sim…
Como é de praxe neste blog(e na minha vida em geral), vamos direto ao assunto: WebServices já fazem parte da rotina dos programadores, seja qual for a plataforma, e alias em Delphi é algo muito simples de se fazer.
Primeira coisa, se quiserem testar a aplicação de vocês, recomendo que façam um cadastro no Byjg , assim vocês terão acesso a um excelente serviço de busca de CEP’s, que será usado como exemplo.
Bom, feito o cadastro abram o Delphi (no meu caso a Versão 7) e faça File->New->Other aba WebService, e abra “WSDL importer”
Na Caixa que segue digite o endereço do WDSL,no caso, http://www.byjg.com.br/site/webservice.php/ws/cep?WSDL, isto fará a importação de uma interface necessária para a utilização do WEBSERVICE.Depois de avançar finalize, assim você verá que será criada uma unit chamada CEP com o seguinte código.
CODE
// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : http://www.byjg.com.br/site/webservice.php/ws/cep?WSDL
// Encoding : utf-8
// Version  : 1.0
// (27/3/2010 13:28:27 – 1.33.2.5)
// ************************************************************************ // unit cep;
interface
uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;
type
  // ************************************************************************ //
  // The following types, referred to in the WSDL document are not being represented
  // in this file. They are either aliases[@] of other types represented or were referred
  // to but never[!] declared in the document. The types from the latter category
  // typically map to predefined/known XML or Borland types; however, they could also
  // indicate incorrect WSDL documents that failed to declare or import a schema type.
  // ************************************************************************ //
  // !:string          – “http://www.w3.org/2001/XMLSchema”
  ArrayOfstring = array of WideString;          { “urn:CEPService” }
  // ************************************************************************ //
  // Namespace : urn:http://www.byjg.com.br
  // soapAction: urn:CEPServiceAction
  // transport : http://schemas.xmlsoap.org/soap/http
  // style     : rpc
  // binding   : CEPServiceBinding
  // service   : CEPService
  // port      : CEPServicePort
  // URL       : http://www.byjg.com.br/site/webservice.php/ws/cep
  // ************************************************************************ //
  CEPServicePort = interface(IInvokable)
  ['{EC28595B-95D2-DE51-E5B1-57B81D4826D3}']
    function  obterVersao: WideString; stdcall;
    function  obterLogradouro(const cep: WideString): WideString; stdcall;
    function  obterLogradouroAuth(const cep: WideString; const usuario: WideString; const senha: WideString): WideString; stdcall;
    function  obterCEP(const logradouro: WideString; const localidade: WideString; const UF: WideString): ArrayOfstring; stdcall;
    function  obterCEPAuth(const logradouro: WideString; const localidade: WideString; const UF: WideString; const usuario: WideString; const senha: WideString): ArrayOfstring; stdcall;
  end;
function GetCEPServicePort(UseWSDL: Boolean=System.False; Addr: string=”; HTTPRIO: THTTPRIO = nil): CEPServicePort;
implementation
function GetCEPServicePort(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): CEPServicePort;
const
  defWSDL = ‘http://www.byjg.com.br/site/webservice.php/ws/cep?WSDL’;
  defURL  = ‘http://www.byjg.com.br/site/webservice.php/ws/cep’;
  defSvc  = ‘CEPService’;
  defPrt  = ‘CEPServicePort’;
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = ”) then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as CEPServicePort);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;
initialization
  InvRegistry.RegisterInterface(TypeInfo(CEPServicePort), ‘urn:http://www.byjg.com.br’, ‘utf-8′);
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(CEPServicePort), ‘urn:CEPServiceAction’);
  RemClassRegistry.RegisterXSInfo(TypeInfo(ArrayOfstring), ‘urn:CEPService’, ‘ArrayOfstring’);
end.
Repare que há uma interface chamada “CEPServicePort”, e uma função chamada “GetCEPServicePort” que retorna um objeto do tipo da interface citada.Em resumo, é só usar está função para pegar o objeto e utilizar as funções de de busca de Cep citadas nesta parte:
  CEPServicePort = interface(IInvokable)
  ['{EC28595B-95D2-DE51-E5B1-57B81D4826D3}']
    function  obterVersao: WideString; stdcall;
    function  obterLogradouro(const cep: WideString): WideString; stdcall;
    function  obterLogradouroAuth(const cep: WideString; const usuario: WideString; const senha: WideString): WideString; stdcall;
    function  obterCEP(const logradouro: WideString; const localidade: WideString; const UF: WideString): ArrayOfstring; stdcall;
    function  obterCEPAuth(const logradouro: WideString; const localidade: WideString; const UF: WideString; const usuario: WideString; const senha: WideString): ArrayOfstring; stdcall;
  end;
Muito bem, mas vamos mastigar um pouco, tem algumas manha ainda, vá até a a paleta WEBServices, e arraste um componente HTTPRIO.
Neste componente, você encontrará todas as propriedades necessárias para se conectar a um webService, no entanto configure apenas o proxy de houver algum, porque o restante das configurações serão retornados pela função “function GetCEPServicePort(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): CEPServicePort; ” Reparem que, o ultimo parâmetro de função é exatamente um componente HTTPRIO, pois a função ira usar parte de suas configurações(que não sejam relacionadas ao serviço em si, mas em relação a rede proxy etc.), para retornar um objeto filho de HTTPRIO (sim um filho, olha esse retorno Result := (RIO as CEPServicePort); , pegando o componente e fazendo o polimorfismo ).
Depois da explicação terica vamos ao código:
CODE
procedure TForm1.Button1Click(Sender: TObject);
var ser: CEPServicePort;
begin       ser:= GetCEPServicePorT(false,”,HTTPRIO1);
      memo1.text:=    ser.obterLogradouroAuth(Edit1.Text,’usuario’,senha’); // o usuario e senha são aqueles que você cadastrou no site dito no começo do artigo
end;
Simplesmente um botão que quando clicado, faz instãncia de um CEPServicePort, atraves da função getCEPServicePort,usando parte da configuração feita no componente ,HTTPRIO1;
Depois é só usar qualquer método declarado na interface CEPServicePort , e no nosso caso usaremos o método obterLogradouroAuth., e simplesmente  jogar o valor do Lagradouro em um MEMO,

Ressaltando que quase todos os WebServices trabalham da mesma forma, alguns métodos de interfaces geradas retornam tipos especificos, mas basta usá-los pois estarão disponíveis na unit baixada através do WSDL;
é isso ai… qualquer dúvida ou sugestão? deixe nos recados!

0 comentários: