Escolar Documentos
Profissional Documentos
Cultura Documentos
Tecnologia DataSnap
Pgina 1 de 33
Pgina 2 de 33
Pgina 3 de 33
Figura 01
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
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.
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
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
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
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
Figura 10
Figura 11
Pgina 10 de 33
Pgina 11 de 33
Pgina 12 de 33
Pgina 13 de 33
Pgina 14 de 33
Figura 03 - WebDataModule
Pgina 15 de 33
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
Pgina 17 de 33
Pgina 18 de 33
Pgina 19 de 33
Figura 01
Figura 02
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
Figura 06
Figura 07
Figura 08
Pgina 21 de 33
Pgina 22 de 33
Figura 01
Figura 02
Figura 03
Pgina 23 de 33
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.
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
Pgina 25 de 33
Pgina 26 de 33
89. ClientDataSetCliente.Close;
90. ClientDataSetCliente.Params[0].AsLargeInt:=ID;
91. ClientDataSetCliente.Open;
92. Result:=ClientDataSetCliente;
93. end;
94.
95. end.
Comentrio
44
47
Define um objeto JSONValue, especfico para armazenar valor retornado pela lista
TJOSONArray.
56
58 a 59
66 a 77
77
81 a 84
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.
Pgina 27 de 33
Figura 01
- Testando o mtodo ConsultarClienteID, que exige um valor numrico de entrada retornando o registro
cuja a chave primria corresponda.
Figura 02
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
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"]
}
Pgina 30 de 33
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.
Figura 02
Figura 03
Pgina 31 de 33
Figura 04
Pgina 32 de 33
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
*/