DataSnap 2010 – Enviando e recebendo objetos
in Delphi (Win32) by Andreano Lanusse — 25 de setembro de 2009 at 8:37 | 22 comments
Uma 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
Posts relacionados
- Utilizando generics para transformação genérica de Objetos em DataSnap 2010
- DataSnap 2010 – enviando e recebendo ARRAY de strings, numbers e outros tipos
- Utilizando callback em DataSnap 2010
- Teste nosso servidor DataSnap XE instalado no Amazon Cloud
- DataSnap XE e Windows Azure – RAD Studio XE Preview #3
- Delphi Tour 2010 – slides e exemplos disponibilizados para download
Tags: DataSnap Delphi (Win32) Embarcadero JSON
Tags
Posts Recentes
Teste nosso servidor DataSnap XE instalado no Amazon Cloud
Delphi (Win32) | setembro 3, 2010 | 0 comments
Disponibilizada nova versão do Delphi XE, C++Builder XE, Delphi Prism XE e RadPHP XE
Delphi (Win32), Delphi Prism (.NET), RadPHP (Delphi for PHP) | agosto 31, 2010 | 9 comments
Vídeos
Usando Rapid SQL XE com InterBase e Firebird
Database | junho 29, 2010 | 3 comments
Delphi, ER/Studio e DB Optimizer em ação
Database, Delphi (Win32), Delphi Prism (.NET) | maio 25, 2010 | 1 comment
Mais previews sobre a próxima versão do Delphi for PHP
RadPHP (Delphi for PHP) | maio 7, 2010 | 14 comments
Apresentações do Delphi Conference Online disponibilizadas para download
Delphi (Win32) | fevereiro 27, 2010 | 5 comments









Developer Network
22 Comments
[...] 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/ [...]
[...] 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 [...]
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
[...] 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 [...]
Oi Everson, não conheço em detalhes esta biblioteca mas parece interessante
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.
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.
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…
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.
[...] 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 [...]
Rafael acabei de publicar um post mostrando como fazer a conversão genérica.
Obrigado pelo comentário.
Tinha feito algo para parecido, também usando uma classe-base para herdar meus objetos, mas com generics ficou bem mais limpo.
Obrigado
Andreano.
Alguma consideração sobre a pergunto do Márcio Costa? Eu gostaria de tranferir objetos TClientDataSet ou TSQLQuery!
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.
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?
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.
Oi Juliano, obrigado.
Fica lá até você destruir o objeto do server, uma vez passado para o cliente é outra instância.
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
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.
[...] 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. [...]
Olá Parabéns pelo Artigo,
Como eu testo o retorno deste desta aplicação servidora via http??
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