Júnior Oliveira

C Sharp; Delphi; ASP .NET; PHP; Javascript;

JSON (JavaScript Object Notation) e Generics no Delphi

18 Nov 2010 delphi, generics, json

Olá pessoal, mais um post sobre Delphi desta vez um demonstrar duas novas tecnologias que está sendo muito melhoradas no Delphi deste a versão 2009 até a ultima versão o Delphi XE.

Generics é uma forma de poder passar parâmetro de tipos para classes e métodos possibilitando assim reutilização de código por exemplo e JSON (JavaScript Object Notation) é uma forma de troca de dados entre aplicações semelhante ao XML porém com uma sintaxe bem mais simples e leve. O Delphi XE como algumas versões anteriores dá suporte a implementação usando JSON, em nosso exemplo vamos criar um método totalmente genêrico que recebe um objeto e um tipo e vamos usar o JSON para formatar este objeto e gravar no disco usando a nova classe de IO (input/output) do Delphi e um método de leitura deste arquivo no formato JSON e retornar o mesmo a um Objeto novamente passando o tipo do objeto e o caminho onde se encontra o arquivo.

Primeiro vamos criar uma nova classe do tipo TPessoa.

 1 type
 2   TPessoa = class
 3   private
 4     { Private declarations }
 5     FPessIden: Integer;
 6     FPessNome: string;
 7 
 8   public
 9     { Published declarations }
10     property PessIden: Integer read FPessIden write FPessIden;
11     property PessNome: string read FPessNome write FPessNome;
12 
13   end;

Para conseguirmos desenvolver nossos métodos temos antes que adicionar ao uses as unit's sitadas abaixo, acima de cada unit tem a descrição de sua função no projeto.

 1 uses
 2   SysUtils,
 3 
 4   { Unit que contem os novos metodos de I/O }
 5   IOUtils,
 6 
 7   { Unit's necessarioas para usar JSON }
 8   DBXJSONReflect, DBXJSON,
 9 
10   { Unit necessaria para usar Generic }
11   Generics.Collections;

Agora vamos criar nossa classe que irá conter os métos necessários para carregar e salvar os dados no disco. O class antes da function indica que estes métodos serão státicos não é necessário instânciar a classe TJSONTools para usar estes métodos e a descrição T : class indica que este método recebe um tipo e que a variável obj passada por parâmetro é deste tipo, e na outra função que ela retorna o tipo especificado.

1 type
2   TJSONTools = class
3     public
4     { Public declarations }
5     class function saveFileJSON<T : class>(obj: T; const filePath: string): Boolean;
6     class function loadFileJSON<T : class>(const filePath: string): T;
7 
8   end;

Agora nosso método que irá gravar no disco o objeto da classe descrita acima.

 1 class function TJSONTools.saveFileJSON<T>(obj: T; const filePath: string): Boolean;
 2 var
 3   Marshal: TJSONMarshal;
 4 
 5 begin
 6   Marshal := TJSONMarshal.Create(TJSONConverter.Create());
 7   try
 8     try
 9       TFile.WriteAllText(filePath, (Marshal.Marshal(obj) as TObject).ToString);
10 
11       Result := True;
12     except
13       Result := False;
14     end;
15   finally
16     FreeAndNil(Marshal);
17   end;
18 end;

Agora o método responsável por ler o arquivo e carregar novamente os dados para um objeto.

 1 class function TJSONTools.loadFileJSON<T>(const filePath: string): T;
 2 var
 3   Unmarshal: TJSONUnMarshal;
 4   obj: TJSONObject;
 5 
 6 begin
 7   Unmarshal := TJSONUnMarshal.Create();
 8   try
 9     try
10       if not(FileExists(filePath)) then
11         Exit(nil);
12 
13       obj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(TFile.ReadAllText(filePath)), 0) as TJSONObject;
14 
15       Result := T(Unmarshal.Unmarshal(obj));
16     except
17       Exit(nil);
18     end;
19   finally
20     FreeAndNil(Unmarshal);
21   end;
22 end;

Agora uma forma de poder usar nossa classe.

 1 var
 2   objPessoa: TPessoa;
 3 
 4 begin
 5   objPessoa:= TPessoa.Create();
 6   objPessoa.PessIden := 1;
 7   objPessoa.PessNome := 'A Junior';
 8 
 9   if (TJSONTools.saveFileJSON<TPessoa>(objPessoa, 'C:\pessoa.txt')) then
10     ShowMessage('Criou o arquivo no caminho: ' + #13 + ' C:\pessoa.txt');
11 
12   objPessoa := TJSONTools.loadFileJSON<TPessoa>('C:\pessoa.txt');
13   if (Assigned(objPessoa)) then
14   begin
15     ShowMessage(
16       'PessIden: ' + IntToStr(objPessoa.PessIden) + #13 +
17       'PessNome: ' + objPessoa.PessNome
18     );
19   end
20   else
21     ShowMessage('Nao foi possivel des-serializar o objeto');
22 end;

Este foi apenas um exemplo didático usando JSON e Generics no Delphi estes métodos ainda podem ser refatorados e criado validações para tratar possiveis erros de parâmetros que podem ser identificados criando testes unitários sobres estes métodos. Obrigado pela visita e até a próxima.