DataSnap 2010 – Enviando e recebendo objetos

 

Delphi iconUma das perguntas frequentes dos usuários de Delphi 2009 e que utilizam DataSnap para criação de objetos é sobre a transferência de objetos entre cliente e servidor. No DataSnap 2009 estavamos limitados aos data types do dbxExpress, agora com o DataSnap 2010 que acompanha o Delphi 2010, isso é totalmente possível.

DataSnap 2010 traz o suporte a JSON (JavaScript Object Notation) que é uma formatação leve de troca de dados, totalmente independente de linguagem, futuramente vou comentar mais sobre JSON e suas vantagens, para começar este post irá mostrar como transferir objetos entre cliente e servidores DataSnap, sendo que ambos cliente e servidor são aplicações Delphi.

Para começar vamos definir uma classe chamada TCustomer.


unit Customer;

interface

uses
   DBXJSON, DBXJSONReflect, SysUtils;

type
   TMaritalStatus = (msMarried, msEngaged, msEligible);

TCustomer = class
    private
       FName: string;
       FAge: integer;
       FMaritalStatus: TMaritalStatus;
    public
        property Name: string read FName write FName;
        property Age: integer read FAge write FAge;
        property MaritalStatus: TMaritalStatus read FMaritalStatus write FMaritalStatus;

        function toString : string;override;
  end;

Para transferir objetos em DataSnap estes devem descender the TJSONObject, no caso de não ser um objeto descendente você terá que utilizar as classes TJSONMarshal e TJSONUnMarshal para efetuar a transformação dos objetos. Sendo assim os métodos abaixo irão efetuar a conversão dos mesmos.


unit Customer;

  function CustomerToJSON(customer: TCustomer): TJSONValue;
  var
    m: TJSONMarshal;
  begin
    if Assigned(customer) then
    begin
      m := TJSONMarshal.Create(TJSONConverter.Create);
      try
        exit(m.Marshal(customer))
      finally
        m.Free;
      end;
    end
    else
      exit(TJSONNull.Create);
  end;

  function JSONToCustomer(json: TJSONValue): TCustomer;
  var
     unm: TJSONUnMarshal;
  begin
    if json is TJSONNull then
      exit(nil);
    unm := TJSONUnMarshal.Create;
    try
      exit(unm.Unmarshal(json) as TCustomer)
    finally
      unm.Free;
    end;
  end;

Com isso temos classe TCustomer pronta para trafegar entre cliente e servidor, assim sendo basta implementar um Server Method que retorne um TJSONValue a partir da transformação de TCustomer, como o exemplo abaixo.


// protected
function TServerMethods.GetCustomer: TCustomer;
begin
  Result := TCustomer.Create;
  Result.Name := 'Pedro';
  Result.Age := 30;
  Result.MaritalStatus := msEligible;
end;

// public
function TServerMethods.GetJSONCustomer(): TJSONValue;
var
  myCustomer: TCustomer;
begin
  myCustomer := GetCustomer;
  Result := CustomerToJSON(myCustomer);
  myCustomer.Free;
end;

No lado cliente ao executar o método GetJSONCustomer será necessário efetuar a transformação de TJSONValue para TCustomer, utilizando o método JSONToCustomer.


var
  proxy: TServerMethodsClient;
  myJSONCustomer: TCustomer;
begin

  try
    proxy := TServerMethodsClient.Create(SQLConnection1.DBXConnection);
    myJSONCustomer := JSONToCustomer(proxy.myJSONCustomer);

    Button1.Caption := myJSONCustomer.ToString;
    myJSONCustomer.Free;
  finally
    SQLConnection1.CloneConnection;
    proxy.Free;
  end;
end;

Muito mais pode ser feito, como retornar Arrays de objetos, classes mais complexas, etc. Estarei abordando estes temas em futuros posts.

Download do código fonte

Compartilhe e divirta-se:
  • Print
  • Twitter
  • Facebook
  • Yahoo! Bookmarks
  • Digg
  • Sphinn
  • del.icio.us
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • Live
  • Add to favorites

Posts relacionados

Tags:

 
 
 
 

22 Comments

 
  1. [...] Setembro 25, 2009 por marlonsouza Agora, no Delphi 2010, é possível transferir objetos entre entre clientes e servidores DataSnap. Leia mais a respeito no endereco http://www.andreanolanusse.com/blogpt/datasnap-2010-enviando-e-recebendo-objetos/ [...]

  2. [...] sequência ao tema transferência de objetos com DataSnap o qual iniciei escrevendo sobre a transferência de um simples objeto, o qual é pré-requisito para entender este artigo, neste post descrevo como transferir uma lista [...]

  3. Everson Novka disse:

    Olá Andreano, bem interessante esses novos recursos do Delphi 2010, a minha licença do novo Delphi deve estar chegando nessa semana, já estou aqui pirando para poder escrever meus serviços com datasnap. Alguns dias atrás eu escrevi um mini-artigo sobre exportação de dados de um dataset para um arquivo JSON utilizando versões anteriores ao Delphi 2010, utilizei a biblioteca lkjson, q é opensource. Se tiver interesse, segue meu blog: http://www.eversonnovka.com

    []‘s

  4. [...] sequência ao tema transferência de objetos com DataSnap o qual iniciei escrevendo sobre a transferência de um simples objeto, e depois sobre o envio de array objetos, agora vamos descrever como enviar array que contenha [...]

  5. Andreano Lanusse disse:

    Oi Everson, não conheço em detalhes esta biblioteca mas parece interessante

  6. Marcio Costa disse:

    Caro Andreano,

    Ótimo post parabéns.

    Uma pequena dúvida: Há algo pronto, no delphi 2010, para enviar/receber objetos mais complexos como por exemplo um TClientDataSet?
    Obrigado.

  7. Bruno disse:

    Muito bom o artigo, estou querendo fazer algo parecido com um Browser, onde todos os meus formulários ficariam do lado do Servidor e eu teria no lado Cliente somente uma carcaça para ler esses objetos do Servidor e traduzir. Acho que isso é possível usando o JSON, vou pesquisar mais, de qq forma obrigado.

  8. Rafael Soares disse:

    Boa tarde,
    Teria algum exemplo para a conversão genérica de objetos para JSON?
    Escrever dois métodos para para cada classe não me parece uma boa coisa. A conversão genérica de um objeto para JSON eu consegui, agora de JSON para um objeto está difícil…

  9. Andreano Lanusse disse:

    Rafael, agora não tem um método genérico, mas você pode criar um utilizando generics :)

    Para as próximas versões isso será transparente, mas você também terá a opção de controlar como converter.

  10. [...] meu post anterior “DataSnap 2010 – Enviando e Recebendo objetos” mostrei como transferir objetos através de JSON objects, nos comentários relacionados a este post [...]

  11. Andreano Lanusse disse:

    Rafael acabei de publicar um post mostrando como fazer a conversão genérica.

    Obrigado pelo comentário.

  12. Rafael Soares disse:

    Tinha feito algo para parecido, também usando uma classe-base para herdar meus objetos, mas com generics ficou bem mais limpo.

    Obrigado

  13. Eduardo Freire disse:

    Andreano.
    Alguma consideração sobre a pergunto do Márcio Costa? Eu gostaria de tranferir objetos TClientDataSet ou TSQLQuery!

  14. Andreano Lanusse disse:

    Oi Eduardo,

    Na minha opinião não faz sentido, querer transferir TClientDataSet é a mesma coisa que transferir dados e isso ele já faz com o Provider, no caso de TSQLQuery é querer passar SQL isso você faz pelo ClientDataSet, server method ou outra forma.

  15. José Abílio disse:

    Adreano,
    Novamente lhe dando os parabéns pelo ótimo post, mas estou uma dúvida, terei que ter as classes tanto na aplicação cliente quanto na aplicação servidora?
    Isso não seria um retrabalho?
    Ter que refazer toda a estrutura de classes novamente ou no cliente ou no servidor.
    Por exemplo, aqui tenho uma série de classes com toda as regras de negócios e mapeamento objeto relacional, vou ter que fazer isso tudo denovo no servidor, ou tem algum jeito de fazer as regras de negócio no servidor com as classes que já tenho e no cliente apenas chamar elas, de algum modo sem ter que reescrever boa partes delas?

  16. Juliano disse:

    Ola Andreano.
    Primeiramente parabens pelo blog, muito bom msm.

    Seguinte fiz uma implementacao neste genero utilizando as dicas do outro artigo pra deixar a conversao generica, mas estou com uma dúvida.

    Como fica o gerenciamento da memoria no server, exemplo: Eu faco uma requisicao de uma lista, é feita a consulta instancia um JSonArray seta e devolve para a interface, mas a memoria ocupada por esta lista no server continua lah.

    Tem alguma dica.

    Mais uma vez parabéns.

  17. Andreano Lanusse disse:

    Oi Juliano, obrigado.

    Fica lá até você destruir o objeto do server, uma vez passado para o cliente é outra instância.

  18. Juliano disse:

    Certo, mas como faço para destruir os objetos do server, visto que só poderei destruir eles apos a conclusão da solicitação no entanto quando a solicitação é concluída nao tenho mais acesso as objetos instanciado, já que a execução retornou para o cliente.

    Abraço

  19. Silvio Mendes disse:

    Muito bom mesmo esse post sobre datasnap, ainda estou me iniciando nisso mas ele demonstra o poder e a simplicidade de uso. Outro ponto é o uso do JSON, que já conhecia, mas no EXTJS que é todo baseado nessa notação.

    Com toda certeza terei perguntas, mas vou explorar mais os códigos aqui.

    Parabéns pelas dicas.

  20. [...] http://www.andreanolanusse.com/blogpt/datasnap-2010-enviando-e-recebendo-objetos This entry was posted on Thursday, July 15th, 2010 at 11:34 pm. You can follow any responses to this entry through the RSS 2.0 feed. Responses are currently closed, but you can trackback from your own site. [...]

  21. Flávio disse:

    Olá Parabéns pelo Artigo,
    Como eu testo o retorno deste desta aplicação servidora via http??

  22. Paulo disse:

    Exemplo fantastico do uso do DATASNAP, me ajudou muito na migração de uma sistema feio em delphi 2009.

    mas gostaria de saber como enviar e receber dados de um campo BLOB do banco de dados, eu até recebo mas nao consigo enviar. o sistema sempre reclama falando que o JSON nao suporta ARRAY e nem DATA.

    poderia passar um exemplo de como trabalhar com eses tipo de Dado usando o JSON e D2010 ?

    obrigado

 

Leave a Comment

 




XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
 
 
Get Adobe Flash playerPlugin by wpburn.com wordpress themes