DataSnap 2010 – enviando e recebendo ARRAY de strings, numbers e outros tipos

Dando sequência ao tema transferência de objetos com DataSnap e Delphi 2010 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 tipos distintos.

Para retornar tipos String, Integer, Double, Real, Boolean e outros tipos, utilizamos a classe TJSONValue que serve como base para as classes TJSONString, TJSONNumber, TJSONTrue, TJSONFalse, TJSONNull e TJSONObject. O retorno de uma lista destes tipos é representando pelo TJSONArray, comentando no meu post anterior.

Abaixo exemplo de um ServerMethod que retorna um TJSONArray o qual contém vários items, cada um deles de tipos diferentes.

function TDSServerMethods.ListofDifferentTypes: TJSONArray;
var
  strval: TJSONString;
  trueval : TJSONTrue;
  falseval : TJSONFalse;
  numval: TJSONNumber;
  objval : TJSONObject;
begin
  Result := TJSONArray.Create;

  strval := TJSONString.Create('Return String value from DataSnap Server');
  Result.AddElement(strval);

  numval := TJSONNumber.Create(100);
  Result.AddElement(numval);

  numval := TJSONNumber.Create(99.99);
  Result.AddElement(numval);

  trueval := TJSONTrue.Create;
  Result.AddElement(trueval);

  falseval := TJSONFalse.Create;
  Result.AddElement(falseval);

  Result.AddElement(CustomerToJSON(GetCustomer));

end;

Agora basta acessar o método através da aplicação cliente o qual será capaz de reconhecer todos os tipos de objetos aqui enviados.

var
  proxy: TDSServerMethodsClient;
  mySingleValue: TJSONValue;
  allValues: TJSONArray;
  i: Integer;
begin

  proxy := nil;
  try
    proxy := TDSServerMethodsClient.Create
      (DMClientContainer.MyDSServer.DBXConnection);
    allValues := proxy.ListofDifferentTypes;
    for i := 0 to allValues.Size - 1 do
    begin
      mySingleValue := allValues.Get(i);

      if mySingleValue is TJSONString then
        MMLog.Lines.Add('TJSONString value ' + mySingleValue.Value)
      else if mySingleValue is TJSONNumber then
        MMLog.Lines.Add('TJSONNumber value ' + mySingleValue.Value)
      else if mySingleValue is TJSONTrue then
        MMLog.Lines.Add('TJSONTrue value ' + mySingleValue.ToString)
      else if mySingleValue is TJSONFalse then
        MMLog.Lines.Add('TJSONFalse value ' + mySingleValue.ToString)
      else if mySingleValue is TJSONObject then
        MMLog.Lines.Add('TJSONObject value ' + mySingleValue.ToString);

    end;

  finally
    proxy.Free;
  end;

end;

Ao executar o retorno será:

TJSONString value Return String value from DataSnap Server
TJSONString value 100
TJSONString value 99.99
TJSONTrue value true
TJSONFalse value false
TJSONObject value {“type”:”Customer.TCustomer”,”id”:1,”fields”:{“FName”:”Andreano Lanusse”,”FAge”:32,”FMaritalStatus”:”msMarried”}}

No caso to TJSONObject foi utilizado o método ToString o qual retorna a representação do objeto em formato JSON, através da classe TJSONUnMarshal convertermos para TCustomer, esta conversão foi tratada no posto anterior.

Download do código fonte

2 respostas
  1. Rodrigo Rodrigues
    Rodrigo Rodrigues says:

    Olá Andreano, tenho acompanhado seus poost e quero deixar meus parabéns.

    antes de dizer minha dúvida, gostaria de saber quando vai ter conferência do delphi no RN.

    Bem, vamos lá

    fiz esses exemplos mostrados para retornar um array do tipo TJSONArray e funcionou muito bem, depois irei fazer um teste de stress remotamente para ver o desempenho real do datasnap. Se vc já tiver algum case em relação a isso, gostaria de saber.

    eu realizei uma pequena alteração no seu exemplo, eu adicionei uma propriedade a classe TCustumer chamada Type, que por sua vez é do tipo TType, até ai tudo bem, só que ao tentar usar o método de conversão CustomerToJSON no server side, é levantada uma exceção, mais precisamente na linha exit(m.Marshal(customer)) .

    a mensagem é : Exception class EConversionError with message ‘Internal: Type TThread.TSynchronizeRecord is not currently supported’.

    nesse caso, ele não suporta converter Objetos (TCustumer) quando tem propriedade que é de outro tipo? existe uma forma de contornar isso?

    não sei se fui claro.

    valew, e mais uma vez, parabéns pelos seus Posts!

    Att.

    Rodrigo Rodrigues

    Responder
  2. Wagner Freitas
    Wagner Freitas says:

    Andreano ,
    Estou utilizando JSON transferir dados entre server e client, e gostaria que você comente aqui ou no NDDV
    No exemplo da classe “customer” , você usou dados simples na classe ou melhor dados primários , mas se eu colocar um campo por exemplo TStream , as coisas mundão de figura.
    Não funcionou com campo TStream, analisei e estudei o problema.
    Trabalhei e pesquisei sobre o assunto e achei duas referencias (site do(a) Daniele Teti’s sempre uma excelente referencia e o do Adrian http://blogs.embarcadero.com/adrian/2009/08/19/json-types-for-server-methods-in-datasnap-2010/).
    Em resumo para poder transferir um tipo de dado diferente aos que já existem na classe do JSON , e devo criar um RegisterConverter / RegisterReverter ?
    E você pode perguntar porque quero transferir um TStream ? Um Stream não é portavel para outras linguagens teríamos grandes problemas para fazer isso.
    Okey , okey eu sei disso, porem pergunto somente por questões didáticas, porque esbarrei neste problema mas vou utilizar outro tipo de dado para o meu caso.
    Não deixe de postar , seus posts são de grande valia.

    Responder

Deixe uma resposta

Want to join the discussion?
Feel free to contribute!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *


Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.