fbpx

Transferindo imagem via Datasnap REST – Parte 2


Dando continuidade a transferência de imagem via Datasnap REST, nesta postagem vamos construir um App cliente multiplataforma para receber o arquivo trafegado. Confira!

Vale lembrar que na postagem TRANSFERINDO IMAGEM VIA DATASNAP REST – PARTE 1 criamos o nosso servidor DataSnap REST contendo o método personagens que nos lista o conteúdo da tabela Personagens retornando um JSONArray

Como mencionei na postagem anterior a transferência de imagens foi tema de uma conversa minha com George De Luca, no final do ano passado. Embora tenha abordado com De Luca o tema teoricamente, somente em agosto desse ano consegui disponibilizar tempo para implementar este exemplo, que por sinal foi fruto da viabilidade de um leitor aqui do blog, Marcos Paulo Berger… fica aqui o agradecimento pela escolha. Agradecimento também ao companheiro na troca de ideias o sempre presente Cesar Romero, MVP da Embarcadero, valeu mister!

Criando o App Client

Como consumiremos um servidor REST, vamos criar um App Client multiplataforma. Via Delphi vamos em File -> New -> Other -> Delphi Projects -> Multi Device Project -> Blank Application.

Basicamente precisamos de 1 Edit para informar o ID do personagem a solicitarmos em nossa requisição, 1 Image para exibir o resultado e 1 Button para executar nossa requisição. Isso nos bataria para definir a interface de usuário. Entretanto adicionei mais 1 Edit para informarmos o endereço IP de nossa aplicação servidora e um 1 Label para exibir o resultado do nome do personagem.

Ao final do processo teremos uma tela parecida com esta abaixo:

UI para o Cliente a receber a Imagem via DataSnap REST

Note que já consta na nossa tela os componentes responsáveis pela comunicação com o Servidor, vamos falar deles agora.

Comunicação via biblioteca REST Client

A Biblioteca REST Client possui componentes para prover de maneira rápida e prática a comunicação com serviços REST. Para maiores informações acesse Biblioteca REST Client na Embarcadero DocWiki. Não vou explicar cada um deles, vamos direto efetuar a configuração de cada um dos elementos:

object RESTClient1: TRESTClient
Accept = 'application/json, text/plain; q=0.9, text/html;q=0.8,'
AcceptCharset = 'UTF-8, *;q=0.8'
BaseURL = 'http://localhost:8080/datasnap/rest/TServerMethods1/personagens/1/1'
end
object RESTRequest1: TRESTRequest
Client = RESTClient1
Response = RESTResponse1
end
object RESTResponse1: TRESTResponse
ContentType = 'application/json'
RootElement = 'result[0]'
end

Com essas poucas linhas configuramos a Biblioteca REST Client e comunicação de nossa Aplicação Client, com o servidor.

Codificando a chamada para a transferência

Entramos agora na codificação para que nossa App Client efetue a chamada ao servidor e consequentemente execute a transferência da imagem. Antes vamos preparar o processo adicionando as seguintes Units na cláusula uses da seção Implementation :

implementation
{$R *.fmx}
uses
  System.JSON.Readers,
  System.JSON,
  System.JSON.Types,
  System.NetEncoding;

Vamos codificar o evento onClick do Button1 como abaixo, note que já comentei todo o código:

procedure TFormClient.Button1Click(Sender: TObject);
var
  // Traz o Stream do Servidor
  Recebido : TStringStream;
  // Armazena a decodificação
  Foto : TMemoryStream;
  // Recebe a response da chamada
  SR : TStringReader;
  // Processa a response como JSON
  JR : TJsonTextReader;
begin
  if EditHost.Text = EmptyStr then
    EditHost.Text := 'localhost';

  //  Como o foco é a transferência não fiz a criação de parâmetros no request
  // Definimos a url base da requisição
  // adicionamos 3 parâmetros no format: Host, MinID e MaxID
  RESTClient1.BaseURL := Format('http://%s:8080/datasnap/rest/TServerMethods1/personagens/%u/%u',
                                [EditHost.Text, StrToInt(edit1.text), StrToInt(edit1.text)]);
  // Executamos a requisição
  RESTRequest1.Execute;
  // Armazenamos o conteúdo da resposta da requisição
  SR := TStringReader.Create(RESTResponse1.Content);
  try
    // Criamos o JSON a partir do armazenamento acima
    JR := TJsonTextReader.Create(SR);
    try
      while JR.Read do
        begin
          // Verifica se é Propriedade
          if jr.TokenType = TJSonToken.PropertyName then
            begin
              // Se é a propriedade FOTO
              if UpperCase(jr.value.toString) = 'FOTO' then
                begin
                  jr.Read;
                  Recebido := TStringStream.Create(jr.Value.ToString);
                  Recebido.Position := 0;
                  //Cria o stream que vai receber o conteúdo depois de trafegado
                  Foto := TMemoryStream.Create;
                  // Decodifica a transferência do Stream de Recebido para Foto
                  TNetEncoding.Base64.Decode(Recebido, Foto);
                  // Posiciona o Stream Foto no início
                  Foto.Position := 0;
                  // Carrega o Stream Foto para a imagem
                  Image1.MultiResBitmap.LoadItemFromStream(Foto, 1);
                  //Libera os Streams da memória
                  Recebido.Free;
                  Foto.Free;
                end
              // Se o for a propriedade nome
              else if UpperCase(jr.Value.ToString) = 'NOME' then
                begin
                  jr.Read;
                  // Atribui seu valor ao label na tela
                  Label1.Text := jr.Value.ToString;
                end;
            end;
        end;
    finally
      jr.Free;
    end;
  finally
    sr.Free;
  end;
end;

Com todos esses comentários o código aparenta ser maior que realmente é, entretanto fiz questão de comentar linha a linha o processo.

O pulo do gato

Você deve ter percebido que a linha 42, na qual efetuamos a decodificação do nosso Stream:

TNetEncodind.Base64.Decode(Recebido, Foto);  

Através dela transformamos o Base64 Recebido passando para o Stream Foto que em seguida é carregado na tela pelo componente Image1.

Executando

Com isso nosso exemplo já está pronto para ser executado, confira no vídeo abaixo:

Você  pode notar que com a utilização das variações de TNetEncoding temos nossa vida simplificada ao extremo.

Como diria o grande mestre Ricardo Barbieri: “Simples assim”!

,

Comente