Você está na página 1de 33

Mini-Curso: Interoperabilidade DataSnap Android

Tecnologia DataSnap

Pgina 1 de 33

Mini-Curso: Interoperabilidade DataSnap Android


Aplicao Multicamadas

Pgina 2 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 3 de 33

Criando um Projeto DataSnap REST


Passo 01
Crie um projeto DataSnap REST conforme ilustrado pela Figura 01, acessando a opo de Menu File |
New | Other... | DataSnap Server. Clique em Ok.
Repare que temos outras opes de servidores, mas, devido ao fato de desejarmos atender (ser
consumido) clientes no alinhados com tecnologia Embarcadero (Delphi, C++Bilder entre outras),
utilizaremos o padro REST como forma de integrao, principalmente na troca de dados.
Como prope este trabalho, exemplificaremos com uma aplicao Android 4.3, consumindo servios do
servidor em questo.

Figura 01

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 4 de 33

Passo 02
Nesta etapa, selecione a opo Stand-alone VCL application. Esta opo permite a implantao do
servio de forma transparente, sem a necessidade de um gerenciador de servio do ambiente
operacional. O prprio projeto, quando em execuo, cria as condies.
A segunda opo, equivale a primeiro, exceto que no apresenta uma interface (Form) para
gerenciamento visual.
Quanto a opo ISAPI, exclusiva do ambiente Windows, necessita que seja configurada no Gerenciador
do Internet Information Servervice. Existe justificativa para assim proceder, quanto a questes de
performance e segurana, mas isso discutvel e contornvel.
Clique no boto Next e sigamos em frente.

Figura 02

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 5 de 33

Passo 03
Aqui procedemos testes para saber se neste Host, a porta 8080 est liberada. Neste caso, em uma
mquina de desenvolvimento, dificilmente ser verdade, uma vez que a porta 8080, quase um padro, j
estaria em uso. Observe a Figura 03, que ilustra este passo.
Clique no boto Test Port, procedendo assim o teste para a porta definida em HTTP Port. Caso no
possa ser usada (ver Figura 04), clique no boto Find Open Port para que o Wizard DataSnap REST
Application possa obter uma porta liberada para uso.

Figura 03

Figura 04
Nota:
A abordagem sobre qual porta utilizar para o servio, vai alm de uma simples escolha aleatrio, sendo
assunto a ser definido pela equipe responsvel pela segurana do ambiente operacional.

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 6 de 33

Por fim, neste caso, aceitamos a porta 1438, que naturalmente, no momento de levantarmos o servio
(ser visto na sequncia), estaremos livres para troc-la.

Figura 05

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 7 de 33

Passo 04
A imagem da Figura 06 trata de uma questo no menos importante, pois configura nosso Servidor de
Aplicao DataSnap a fornecer conectores para aplicativos Mobile. Em nosso caso, conforme abordado
na parte final deste projeto, iremos gera em forma de Proxy, as classes Java necessrias para a
interoperabilidade entre o projeto Android e nosso servio.
Assinale a opo Mobile Connectors e clique em Next para prosseguir.

Figura 06

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 8 de 33

Passo 05
TDSServerModule expe conjuntos de dados e mtodos do servidor para aplicativos cliente. Esta a
definio oficial, encontrada em
http://docwiki.embarcadero.com/RADStudio/XE3/en/Configuring_TDSServerModule
Em termos prticos, pensando em desenvolvimento baseado em camadas, seja camada lgica ou fsica,
utilizamos classes tipadas como TDSServerModule para acomodar rotinas CRUD, mtodos de negcio e
regras de negcio. Isso aponta para as boas prticas de OOP, dando aderncia aos padres de projetos
inerentes, sobretudo, cenrio perfeito para representar a camada Model do padro MVC.
Nota
Este assunto polmico, pois os puristas de OOP, sempre se detendo as formas clssicas de
implementao de classes na forma Java e C#, no consideram desta forma. Esto invariavelmente se
prendendo a codificao na unha dos mtodo e atributos, ignorando o aspecto RAD (Rapid Application
Developer), mas isso deixo para os especialistas.
Vida que segue, clique no boto Next conforme Figura 07 para prosseguir.

Figura 07

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 9 de 33

Passo 06
Agora, finalizando, se oriente pelas imagens das Figuras 08 a 11 para escolha de uma pasta em seu
sistema para acomodar os fontes do projeto.
Aps a escolha do diretrio para armazenamento do projeto, clique no boto Finish e pronto.
Dever cumprido. Conforme prometido, seis passos e o mnimo de configurao e temos um Servidor
DataSnap. Agora, conforme veremos na sequncia, basta implementar mtodos de acesso a dados e
utiliz-los em um projeto cliente REST.

Figura 08

Figura 09

Mini-Curso: Interoperabilidade DataSnap Android

Figura 10

Figura 11

Pgina 10 de 33

Mini-Curso: Interoperabilidade DataSnap Android


Listagens e Interfaces Visuais dos Mdulos do Projeto

Figura 01 - Interface de Grenciamento


Listagem 01 - Classe TForm - Interface administrativa do projeto
unit FormUnit1;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.AppEvnts, Vcl.StdCtrls, IdHTTPWebBrokerBridge, Web.HTTPApp;
type
TForm1 = class(TForm)
ButtonStart: TButton;
ButtonStop: TButton;
EditPort: TEdit;
Label1: TLabel;
ApplicationEvents1: TApplicationEvents;
ButtonOpenBrowser: TButton;
procedure FormCreate(Sender: TObject);
procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
procedure ButtonStartClick(Sender: TObject);
procedure ButtonStopClick(Sender: TObject);
procedure ButtonOpenBrowserClick(Sender: TObject);

Pgina 11 de 33

Mini-Curso: Interoperabilidade DataSnap Android


private
FServer: TIdHTTPWebBrokerBridge;
procedure StartServer;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
Winapi.ShellApi, Datasnap.DSService;
procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
begin
ButtonStart.Enabled := not FServer.Active;
ButtonStop.Enabled := FServer.Active;
EditPort.Enabled := not FServer.Active;
end;
procedure TForm1.ButtonOpenBrowserClick(Sender: TObject);
var
LURL: string;
begin
StartServer;
LURL := Format('http://localhost:%s', [EditPort.Text]);
ShellExecute(0,
nil,
PChar(LURL), nil, nil, SW_SHOWNOACTIVATE);
end;
procedure TForm1.ButtonStartClick(Sender: TObject);
begin
StartServer;
end;
procedure TerminateThreads;
begin
if TDSSessionManager.Instance <> nil then
TDSSessionManager.Instance.TerminateAllSessions;
end;

Pgina 12 de 33

Mini-Curso: Interoperabilidade DataSnap Android


procedure TForm1.ButtonStopClick(Sender: TObject);
begin
TerminateThreads;
FServer.Active := False;
FServer.Bindings.Clear;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FServer := TIdHTTPWebBrokerBridge.Create(Self);
end;
procedure TForm1.StartServer;
begin
if not FServer.Active then
begin
FServer.Bindings.Clear;
FServer.DefaultPort := StrToInt(EditPort.Text);
FServer.Active := True;
end;
end;
end.

Figura 02 - DataModule ServerMethods

Pgina 13 de 33

Mini-Curso: Interoperabilidade DataSnap Android


Listagem 02 - Classe TDSServerModule - Acomoda Mtodos e DataSets
unit ServerMethodsUnit1;
interface
uses System.SysUtils, System.Classes, Datasnap.DSServer, Datasnap.DSAuth;
type
TServerMethods1 = class(TDSServerModule)
private
{ Private declarations }
public
{ Public declarations }
function EchoString(Value: string): string;
function ReverseString(Value: string): string;
end;
implementation
{$R *.dfm}
uses System.StrUtils;
function TServerMethods1.EchoString(Value: string): string;
begin
Result := Value;
end;
function TServerMethods1.ReverseString(Value: string): string;
begin
Result := System.StrUtils.ReverseString(Value);
end;
end.

Pgina 14 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Figura 03 - WebDataModule

Listagem 03 - Classe TWebModule - Infraestrutura do Projeto


unit WebModuleUnit1;
interface
uses
System.SysUtils, System.Classes, Web.HTTPApp, Datasnap.DSHTTPCommon,
Datasnap.DSHTTPWebBroker, Datasnap.DSServer,
Web.WebFileDispatcher, Web.HTTPProd,
DSAuth,
Datasnap.DSProxyDispatcher, Datasnap.DSProxyJavaAndroid,
Datasnap.DSProxyJavaBlackBerry, Datasnap.DSProxyObjectiveCiOS,
Datasnap.DSProxyCsharpSilverlight,
Datasnap.DSProxyJavaScript, IndyPeerImpl, Datasnap.DSClientMetadata,
Datasnap.DSCommonServer;
type
TWebModule1 = class(TWebModule)
DSHTTPWebDispatcher1: TDSHTTPWebDispatcher;
DSServer1: TDSServer;
DSServerClass1: TDSServerClass;
ServerFunctionInvoker: TPageProducer;
ReverseString: TPageProducer;

Pgina 15 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 16 de 33

WebFileDispatcher1: TWebFileDispatcher;
DSProxyGenerator1: TDSProxyGenerator;
DSServerMetaDataProvider1: TDSServerMetaDataProvider;
DSProxyDispatcher1: TDSProxyDispatcher;
procedure DSServerClass1GetClass(DSServerClass: TDSServerClass;
var PersistentClass: TPersistentClass);
procedure ServerFunctionInvokerHTMLTag(Sender: TObject; Tag: TTag;
const TagString: string; TagParams: TStrings; var ReplaceText: string);
procedure WebModuleDefaultAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
procedure WebModuleBeforeDispatch(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
procedure WebFileDispatcher1BeforeDispatch(Sender: TObject;
const AFileName: string; Request: TWebRequest; Response: TWebResponse;
var Handled: Boolean);
procedure WebModuleCreate(Sender: TObject);
private
{ Private declarations }
FServerFunctionInvokerAction: TWebActionItem;
function AllowServerFunctionInvoker: Boolean;
public
{ Public declarations }
end;
var
WebModuleClass: TComponentClass = TWebModule1;
implementation
uses ServerMethodsUnit1, Web.WebReq;
{$R *.dfm}
procedure TWebModule1.DSServerClass1GetClass(
DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);
begin
PersistentClass := ServerMethodsUnit1.TServerMethods1;
end;
procedure TWebModule1.ServerFunctionInvokerHTMLTag(Sender: TObject; Tag: TTag;
const TagString: string; TagParams: TStrings; var ReplaceText: string);
begin
if SameText(TagString, 'urlpath') then
ReplaceText := string(Request.InternalScriptName)
else if SameText(TagString, 'port') then

Mini-Curso: Interoperabilidade DataSnap Android


ReplaceText := IntToStr(Request.ServerPort)
else if SameText(TagString, 'host') then
ReplaceText := string(Request.Host)
else if SameText(TagString, 'classname') then
ReplaceText := ServerMethodsUnit1.TServerMethods1.ClassName
else if SameText(TagString, 'loginrequired') then
if DSHTTPWebDispatcher1.AuthenticationManager <> nil then
ReplaceText := 'true'
else
ReplaceText := 'false'
else if SameText(TagString, 'serverfunctionsjs') then
ReplaceText := string(Request.InternalScriptName) + '/js/serverfunctions.js'
else if SameText(TagString, 'servertime') then
ReplaceText := DateTimeToStr(Now)
else if SameText(TagString, 'serverfunctioninvoker') then
if AllowServerFunctionInvoker then
ReplaceText :=
'<div><a href="' + string(Request.InternalScriptName) +
'/ServerFunctionInvoker" target="_blank">Server Functions</a></div>'
else
ReplaceText := '';
end;
procedure TWebModule1.WebModuleDefaultAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
if (Request.InternalPathInfo = '') or (Request.InternalPathInfo = '/')then
Response.Content := ReverseString.Content
else
Response.SendRedirect(Request.InternalScriptName + '/');
end;
procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
if FServerFunctionInvokerAction <> nil then
FServerFunctionInvokerAction.Enabled := AllowServerFunctionInvoker;
end;
function TWebModule1.AllowServerFunctionInvoker: Boolean;
begin
Result := (Request.RemoteAddr = '127.0.0.1') or
(Request.RemoteAddr = '0:0:0:0:0:0:0:1') or (Request.RemoteAddr = '::1');
end;

Pgina 17 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 18 de 33

procedure TWebModule1.WebFileDispatcher1BeforeDispatch(Sender: TObject;


const AFileName: string; Request: TWebRequest; Response: TWebResponse;
var Handled: Boolean);
var
D1, D2: TDateTime;
begin
Handled := False;
if SameFileName(ExtractFileName(AFileName), 'serverfunctions.js') then
if not FileExists(AFileName) or (FileAge(AFileName, D1) and FileAge(WebApplicationFileName,
D2) and (D1 < D2)) then
begin
DSProxyGenerator1.TargetDirectory := ExtractFilePath(AFileName);
DSProxyGenerator1.TargetUnitName := ExtractFileName(AFileName);
DSProxyGenerator1.Write;
end;
end;
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
FServerFunctionInvokerAction := ActionByName('ServerFunctionInvokerAction');
end;
initialization
finalization
Web.WebReq.FreeWebModules;
end.

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 19 de 33

Primeiro Teste do Projeto DataSnap REST


- Execute o projeto observando o resultado na Figura 01.

Figura 01

- Naturalmente, o servio de segurana do SO solicitar autorizao para implantar o servio no Host.

Figura 02

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 20 de 33

- Observe a Figura 03, onde percebemos os botes de controle do projeto. Clique no boto Start,
provocando o levantar do servio na porta 1438, definida anteriormente. Aqui podemos por questes
administrativas estabelecer outra porta para exposio dos servios neste Host.

Figura 03
- Ainda com foco na Figura 03, clique no boto Open Browser, acompanhando os teste dos mtodos de
exemplo do projeto. Esses passos podem ser observado pelas imagens representadas pelas Figuras 04,
05, 06, 07 e 08.

Figura 04

Figura 05

Mini-Curso: Interoperabilidade DataSnap Android

Figura 06

Figura 07

Figura 08

Pgina 21 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 22 de 33

Escolhendo Plataforma para Compilao


- Um aspecto importante na tecnologia DataSnap, que ela projetada para atender clientes
heterogneos quanto as plataformas de desenvolvimento (linguagens e frameworks), e ainda, em
ambiente Windows fornece suporte a 32 e 64 bits.
- Clicando com o boto direito do mouse sobre o n Target Plataforms, na caixa de dialogo Project
Manager, escolha a opo Add Plataform... e teremos a caixa de dialogo representada pela Figura 01
permitindo a escolha de uma plataforma especfica.

Figura 01

- As Figuras 02 e 03 exibem o resultado desta etapa.

Figura 02

Figura 03

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 23 de 33

Acrescentando DataSets e Mtodos de Negcio


a Classe TDSServerModule
- Conforme demonstrado na Figura 01 desta etapa, implementamos dois DataSets, com respectivos
DataSetProvider visando permitir que clientes DataSnap possam ter acesso aos dados expostos, e por
intermdio dos mesmos, utilizando um componente ClientDataSet, criar o ambiente CRUD necessrio.
- Agora atente para o fato, de que clientes heterogneos como aplicativos Android, entre outros, no
suportam a tecnologia DataSnap, logo, no implementam uma classe ClientDataSet. Ento, voltando os
olhos para o cerne da questo, lembramos que esta apresentao foca justamente o consumo de
servios por um cliente Android. Isso justifica a existncia de dois controles ClientDataSet, pois os
mtodos de negcio os utilizaro para implementar a lgica de acesso a dados.

Figura 01
Nota
Por questes de economia de tempo, no entraremos em detalhes da configurao dos controles da
Figura 01. Apresentaremos apenas na sequncia a listagem com todo o cdigo desta classe, com
comentrios sobre a implementao de mtodos interoperveis pela tecnologia REST.

Mini-Curso: Interoperabilidade DataSnap Android

Listagem 01
1. unit ServerMethodsUnit1;
2.
3. interface
4.
5. uses System.SysUtils, System.Classes, Datasnap.DSServer, Datasnap.DSAuth,
6. Data.DBXMSSQL, Data.DB, Data.SqlExpr, Data.FMTBcd, Datasnap.DBClient,
7. Datasnap.Provider, DBXJSON, DBXJSONReflect;
8.
9. type
10. TServerMethods1 = class(TDSServerModule)
11. SQLConnection: TSQLConnection;
12. SQLDataSetConsCliente: TSQLDataSet;
13. SQLDataSetCliente: TSQLDataSet;
14. DataSetProviderConsCliente: TDataSetProvider;
15. DataSetProviderCliente: TDataSetProvider;
16. ClientDataSetConsCliente: TClientDataSet;
17. ClientDataSetCliente: TClientDataSet;
18. ClientDataSetConsClienteID: TLargeintField;
19. ClientDataSetConsClienteNOME: TStringField;
20. ClientDataSetConsClienteCIDADE: TStringField;
21. ClientDataSetConsClienteESTADO: TStringField;
22. ClientDataSetConsClienteTELEFONE: TStringField;
23. ClientDataSetClienteID: TLargeintField;
24. ClientDataSetClienteNOME: TStringField;
25. ClientDataSetClienteCIDADE: TStringField;
26. ClientDataSetClienteESTADO: TStringField;
27. ClientDataSetClienteTELEFONE: TStringField;
28. private
29. { Private declarations }
30. public
31. { Public declarations }
32. function ConsultarClienteId(ID : LongInt): TDataSet;
33. function ConsultarClienteNome(Nome : String): TDataSet;
34. function IncluirCliente(DataSetCliente : TJSONArray) : String;
35.
36. end;
37.
38. implementation
39.
40. {$R *.dfm}
41.
42. uses System.StrUtils;
43.

Pgina 24 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 25 de 33

44. function TServerMethods1.IncluirCliente(DataSetCliente: TJSONArray): String;


45. var
46. JSONValue : TJSONValue;
47. ArquivoErro : TStringList; ArquivoErroIni : TStringList;
48. i : integer;
49. begin
50. JSONValue:=TJSONValue.Create;
51. try
52.
ClientDataSetCliente.Close;
53.
ClientDataSetCliente.Params[0].AsLargeInt:=-1;
54.
ClientDataSetCliente.Open;
55.
ClientDataSetCliente.Append;
56.
for i := 0 to ClientDataSetCliente.Fields.Count - 1 do
57.
begin
58.
JSONValue:=DataSetCliente.Get(i);
59.
ClientDataSetCliente.Fields[i].AsString:=JSONValue.Value;
60.
end;
61.
if ClientDataSetCliente.ApplyUpdates(0) = 0 then
62.
Result:='Sucesso na incluso.'
63.
else
64.
Result:='No houve sucesso na incluso.';
65.
ClientDataSetCliente.Close;
66. except
67.
on E : Exception do
68.
begin
69.
ArquivoErro := TStringList.Create;
70.
ArquivoErro.Text:=E.Message;
71.
ArquivoErro.SaveToFile('ErroDataSnapREST_Erro.txt');
72.
Result:='Erro no processo.';
73.
end;
74. end;
75. end;
76.
77. function TServerMethods1.ConsultarClienteNome(Nome: String): TDataSet;
78. var
79. Arquivo : TStringList;
80. begin
81. ClientDataSetConsCliente.Close;
82. ClientDataSetConsCliente.Params[0].AsString:=Nome + '%';
83. ClientDataSetConsCliente.Open;
84. Result:=ClientDataSetConsCliente;
85. end;
86.
87. function TServerMethods1.ConsultarClienteId(ID: Integer): TDataSet;
88. begin

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 26 de 33

89. ClientDataSetCliente.Close;
90. ClientDataSetCliente.Params[0].AsLargeInt:=ID;
91. ClientDataSetCliente.Open;
92. Result:=ClientDataSetCliente;
93. end;
94.
95. end.

Tabela 01 - Cometrios da Listagem 01


Linha

Comentrio

44

Define o mtodo de incluso de cliente, com parmetro de entrada do tipo


TJOSONArray (array de pares de valores), retornando uma string contendo uma
mensagem, seja de sucesso ou erro.

47

Define um objeto JSONValue, especfico para armazenar valor retornado pela lista
TJOSONArray.

56

Lao para navegar na coleo TJOSONArray, que aqui representa o parmetro de


entrada do mtodo.

58 a 59

Atribui valor a valor da coleo TJOSONArray aos respectivos campos do DataSet.

66 a 77

Alm de implementar tratamento de exceo, implementa um log em um arquivo teto.


Dispensvel, mas til nesta fase de aprendizado, sobretudo, para acompanhar as falhas
ocorridas pela interao com a aplicao Android.

77

Mtodo que implementa um parmetro de entrada string representando o trecho do


nome a ser pesquisado, retornando curiosamente um tipo DataSet. N prtica, como
vermos na sequncia, ser exportado um Proxy em Java contendo classe e mtodos
adaptando os retornos de mtodo de classes Delphi para objetos Java. Este o grande
lance.

81 a 84

Cdigo trivial Delphi.

87

Idem ao explicado para linha 77, mas, observando o fato de aqui no retornar uma
coleo de registros, mas sim um nico registro baseado no valor de chaveprimria
passado pelo mtodo.

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 27 de 33

Promovendo Teste dos Mtodos de Negcio


- Execute o projeto, e em seguida clique no boto Open Browser. Repare na resposta a este ato,
observando a Figura 01.

Figura 01
- Testando o mtodo ConsultarClienteID, que exige um valor numrico de entrada retornando o registro
cuja a chave primria corresponda.

Figura 02

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 28 de 33

- A Listagem 01 exibe o pacote de dados retornado pelo mtodo. Repare que os registros so
representados por par de valores, onde um valor o nome do campo e o segundo o valor do mesmo.
Uma forma simples de representar o campo e o valor atribudo a ele.
Nota
O fato de o pacote de dados no definir tipo, naturalmente invivel, no atrapalha, pois o tal Proxy a ser
gerado em Java, no nosso exemplo supri isso pois as estruturas (Modelos) sero naturalmente tipados.
Listagem 01
Executed:TServerMethods1.ConsultarClienteIdResult:{
"ID":"1003","result": { "table":
[
["ID",18,0,0,0,8,0,0,false,false,0,false,false],
["NOME",1,1,0,50,51,0,0,false,false,0,false,false],
["CIDADE",1,2,0,50,51,0,0,false,false,0,false,false],
["ESTADO",1,3,0,2,3,0,0,false,false,0,false,false],
["TELEFONE",1,4,0,50,51,0,0,false,false,0,false,false]
],
"ID":[1003],
"NOME":["Anne Malman"],
"CIDADE":["Niteri"],
"ESTADO":["RJ"],
"TELEFONE":["2222 3333"]
}
}
- O mesmo vale para o mtodo ConsultarClientePorNome, exceto, que retorna uma coleo de valores.
Confira os teste conforme Figura 03 e Listagem 02.

Figura 03

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 29 de 33

Listagem 02
Executed:TServerMethods1.ConsultarClienteNomeResult:{
"Nome":"","result":{
"table":
[
["ID",18,0,0,0,8,0,0,false,false,0,false,false],
["NOME",1,1,0,50,51,0,0,false,false,0,false,false],
["CIDADE",1,2,0,50,51,0,0,false,false,0,false,false],
["ESTADO",1,3,0,2,3,0,0,false,false,0,false,false],
["TELEFONE",1,4,0,50,51,0,0,false,false,0,false,false]
],

"ID":[1003,1004,1201,1222,1007,1111,1112,1100,1113,
1001,1223,1005,1002,1006,1115],
"NOME":["Anne Malman","Cristine Branco","Etienne Malman","Evelyn Malman",
"Gabbriel Rodrigues","Leonardo Rodrigues","Luiza Guero Camacho",
"Marina Guero Camacho","Miriam Rodrigues","Nicolas Lael",
"Raphael Malman Costa","Renata Rodrigues","Sophia Guedes Malman",
"Theristies Gomes","Willian Rodrigues"],
CIDADE":["Niteri","Gramado","Rio de Janeiro","Niteroi","Angra dos Reis",
"Rio de Janeiro","Rio de Janeiro","Rio de Janeiro","Rio de Janeiro",
"So Gonalo","Niter[oi","Rio de Janeiro","Niteri","Itabuna","Porto Alegre"],
"ESTADO":["RJ","RS","RJ","RJ","RJ","RJ","RJ","RJ","RJ","RJ","RJ",
"RJ","RJ","BA","RJ"],
"TELEFONE":["2222 3333","3456 098","6655 2345","3344 9966","8899 4567",
"3344 9090","2233 8854","5566 0099","8787 9999","8765 4321",
"7766 2211","8921 3465","43217890","6161 6262","9988 1234"]
}

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 30 de 33

Gerando as Classes Java para Import no Projeto Android


- Esta etapa consiste em utilizar a instruo abaixo, executando-a em uma seo console do ambiente
Windows. Para tanto no menu Iniciar o Windows, na caixa Pesquisar Programa ou Arquivos digite cmd e
tecle Enter. Repare na Figura o1 representando o utilitrio cmd.exe. Mas antes, conforme Figura 01,
coloque o servidor em execuo.
Instruo:
C:\Win32ProxyDownloader.exe -language java_android -host 127.0.0.1:1438 -output C:\PacoteProxyJava
Onde:
Win32ProxyDownloader.exe - Utilitrio gerador do Proxy.
-language java_android - Define a linguagem que as classes sero exportadas.
-host 127.0.0.1:1438 - Define IP (Host) e Porta em que o servio est executando.
-output C:\PacoteProxyJava - Define o endereo onde ser gerado as classes Proxy.

Figura 01

As imagens das Figuras 02 e 03, resumem o processo de gerao de classes proxy. Obsere a
figura 02 contendo a instruo, e em seguida, aps teclar Enter, a interface console do utilitrio
Cmd.Exe exibe o pront c:\, indicando sucesso na processo.

- Observe na imagem da Figura 04 a estrutura de diretrio (C:\PacoteProxyJava) exibindo o pacote Java a


ser implantado no projeto Android.

Mini-Curso: Interoperabilidade DataSnap Android

Figura 02

Figura 03

Pgina 31 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Figura 04

Pgina 32 de 33

Mini-Curso: Interoperabilidade DataSnap Android

Pgina 33 de 33

- Por fim, a titulo de curiosidade, repare na Listagem 01 deste tpico, exibindo o cdigo fonte Java para a
Classe TDataSet gerada. Fazendo uma inspeo bsica, vemos porque a codificao da aplicao cliente
Android facilitada. Por intermdio destas classes Java, invocar mtodos do Servidor DataSnap tarefa
fcil.
Listagem 01
//*******************************************************
//
//
Delphi DataSnap Framework
//
// Copyright(c) 1995-2011 Embarcadero Technologies, Inc.
//
//*******************************************************
package com.embarcadero.javaandroid;
/**
*
* TDataSet is the base class for all dataset components that represent data in rows and columns.
*
*/
public class TDataSet extends TDBXReader {
public TDataSet(TParams params, TJSONObject value) {
super(params, value);
}
/**
* Returns a TDataSet created by the information contained in the JSONObject
*
* @param value a TJSONObject that contains the parameters for create the TDataSet
* @return return the TDataSet object created
* @throws DBXException
*/

public static TDataSet createFrom(TJSONObject value) throws DBXException{


TParams params = TParams.CreateParametersFromMetadata(value
.getJSONArray("table"));
TDataSet dst = new TDataSet(params, value);
return dst;
}

Você também pode gostar