GARANTIR DESCONTO

Fórum Método para converter Json para uma lista de Objetos #523458

19/06/2015

0

Boa tarde pessoal, preciso de um método que converta um arquivo json para uma lista de objetos. Estou tentando utilizar o método UnMarshal da unit REST.JsonReflect, porém ele não esta conseguindo reconhecer o arquivo json. Eu estou pegando esse json de um web service java, eu creio que o erro ocorre porque o delphi não consegue reconhecer o arquivo json sem algumas anotações que geralmente um arquivo json gerado pelo delphi contem.

Obs: Delphi XE6.
Danilo Pereira

Danilo Pereira

Responder

Post mais votado

24/06/2015

fiz uma mudança mas to sem o delphi agora pra testar, em casa a minha esposa pega no meu pé se eu chego com serviço pra fazer kkk
testa ai amnha a gente v, vai precisar tambem pecorrer os enderecos, cupons e fazendas q pelo que vi sao array q podem trazer mais de um registro

var
  Json: WideString;
  e, i: integer;
 
  jl: TlkJSONlist;
  ja: TlkJSONobject;
begin
  try
    Json:=Edit1.Text;
    if Length(Json) > 0 then
    begin
      jl := TlkJSON.ParseText(Json) as TlkJSONlist;
 
      if assigned(jl) then
      begin
       for i:=0 to jl.count-1 do
       begin
        ja := jl.child[i] as TlkJSONobject; //acho que mudando aqui ja resolveria
 
        pessoa.EmptyDataSet;
        pessoa.Append;
        pessoacodigo.AsString:=VarToStr(ja.Field['codigo'].Value);
        pessoastatus.AsString:=VarToStr(ja.Field['status'].Value);
        pessoarazaoSocial.AsString:=VarToStr(ja.Field['razaoSocial'].Value);
        pessoaapelidoFantasia.AsString:=VarToStr(ja.Field['apelidoFantasia'].Value);
        pessoacnpjCpf.AsString:=VarToStr(ja.Field['cpfCnpj'].Value);
        pessoainscEstRg.AsString:=VarToStr(ja.Field['inscEstRg'].Value);
        pessoainscMunicipal.AsString:=VarToStr(ja.Field['inscMunicipal'].Value);
        pessoafone.AsString:=VarToStr(ja.Field['fone'].Value);
 
        Pessoaendereco.AsString:=VarToStr(ja.Field['endereco'].Field['nomeLogradouro'].Value);
        Pessoanumero.AsString:=VarToStr(ja.Field['endereco'].Field['numero'].Value);
        Pessoabairro.AsString:=VarToStr(ja.Field['endereco'].Field['bairro'].Value);
        Pessoacidade.AsString:=VarToStr(ja.Field['endereco'].Field['cidade'].Value);
        Pessoauf.AsString:=VarToStr(ja.Field['endereco'].Field['uf'].Value);
        Pessoacep.AsString:=VarToStr(ja.Field['endereco'].Field['cep'].Value);
 
        pessoa.Post;
       end;
      end else
        ShowMessage('não carregou a lista');
    end;
  except
    on E : Exception do
    begin
      ShowMessage('Erro: '+e.message);
    end;
  end;

Dorivan Sousa

Dorivan Sousa
Responder

Gostei + 3

Mais Posts

19/06/2015

Dorivan Sousa

testou o lkjson? nao vai ser automatico, mas voce vai pder ler o json e alimentar o objeto que vc precisa....
Responder

Gostei + 0

19/06/2015

Danilo Pereira

Comecei a trabalhar com Json no delphi faz pouco tempo, este Lkjson eu não conhecia, você consegue me dar um exemplo com ele?
Responder

Gostei + 0

19/06/2015

Dorivan Sousa

lkJson é uma unit que vc adiciona ao seu projeto.
nesse codigo abaixo eu trato o result de um servidor json em delphi e alimento um clientdataset (vc pode colocar no objeto), por isso eu pego primeiro o filed 'result'... fiz esse ha algum tempo usando o servidor no delphi xe e o cliente no delphi 7.

 
var
  lHTTP: TIdHTTP;
  lStream: TStringStream;
  Retorno: WideString;
  aURL: String;
  i: integer;

  js: TlkJSONobject;
  ja2, ja: TlkJSONlist;
  param: String;
  ip: String;
begin
  try
    if Valida_Lojas(Loja) then
      ip:=DM_Cadastro.QryLojasIP_Fixo.AsString;
      
    param:=IntToStr(Acao)+'/'+Procura+'/'+Data_Inicial+'/'+Data_Final+'/'+Loja;
    aURL:='http://'+IP+':8090/datasnap/rest/TServerMethods1/GetRecebidasJson/'+param;

    lHTTP := TIdHTTP.Create(nil);
    //lHTTP.OnDisconnected:=DM_Json.IdHTTPJsonDisconnected;
    //lHTTP.OnWorkBegin:=DM_Json.IdHTTPJsonWorkBegin;
    //lHTTP.OnWorkEnd:=DM_Json.IdHTTPJsonWorkEnd;

    lStream := TStringStream.Create(Retorno);
    try
      lHTTP.Request.Accept := 'text/javascript';
      lHTTP.Request.ContentType := 'application/json';
      lHTTP.Request.ContentEncoding := 'utf-8';
      lHTTP.Request.BasicAuthentication:=True;
      lHTTP.Request.Username:='user';
      lHTTP.Request.Password:=sSenha_HTTP_Json;

      lHTTP.Get(aUrl, lStream);
      lStream.Position := 0;
      Retorno := lStream.ReadString(lStream.Size);
    finally
      FreeAndNil(lHTTP);
      FreeAndNil(lStream);
    end;

    if Length(Retorno)=0 then
    begin
      lHTTP.Free;
      lStream.Free;
      Result:=False;
    end else
    begin
      js := TlkJSON.ParseText(Retorno) as TlkJSONobject;

      ja2 := js.Field['result'] as TlkJSONlist;

      ja := ja2.child[0] as TlkJSONlist;

      if ja.Count <= 0 then
      begin
        lHTTP.Free;
        lStream.Free;
        Result:=False;
      end else
      begin
        DM_Json.QryRecebidas.EmptyDataSet;
        for i:=0 to ja.Count-1 do
        begin
          DM_Json.QryRecebidas.Append;
          DM_Json.QryRecebidasPARCELA.AsString:=VarToStr(ja.Child[i].Field['parcela'].Value);
          DM_Json.QryRecebidasFATURA.AsString:=VarToStr(ja.Child[i].Field['fatura'].Value);
          DM_Json.QryRecebidasVAL_ATUAL.AsFloat:=StrToFloat(VarToStr(ja.Child[i].Field['val_atual'].Value));
          DM_Json.QryRecebidasVal_Recbto.AsFloat:=StrToFloat(VarToStr(ja.Child[i].Field['val_recbto'].Value));
          DM_Json.QryRecebidasVal_Parcela.AsFloat:=StrToFloat(VarToStr(ja.Child[i].Field['val_parcela'].Value));
          DM_Json.QryRecebidasJuros_Recbto.AsFloat:=StrToFloat(VarToStr(ja.Child[i].Field['juros_recbto'].Value));          
          DM_Json.QryRecebidasDATA_EMISSAO.AsDateTime:=Data_Json(VarToStr(ja.Child[i].Field['data_emissao'].Value));
          DM_Json.QryRecebidasDATA_VENCTO.AsDateTime:=Data_Json(VarToStr(ja.Child[i].Field['data_vencto'].Value));
          DM_Json.QryRecebidasData_Recbto.AsDateTime:=Data_Json(VarToStr(ja.Child[i].Field['data_recbto'].Value));          
          DM_Json.QryRecebidasTPO_COBRANCA.AsString:=VarToStr(ja.Child[i].Field['tpo_cobranca'].Value);
          DM_Json.QryRecebidasCLIENTE.AsString:=VarToStr(ja.Child[i].Field['cliente'].Value);
          DM_Json.QryRecebidasNOM_CLIENTE.AsString:=VarToStr(ja.Child[i].Field['nom_cliente'].Value);
          DM_Json.QryRecebidasSTATUS.AsString:=VarToStr(ja.Child[i].Field['status'].Value);
          DM_Json.QryRecebidasTpo_Recbto.AsString:=VarToStr(ja.Child[i].Field['tpo_recbto'].Value);
          DM_Json.QryRecebidasRecebida_na_Loja.AsString:=VarToStr(ja.Child[i].Field['recebida_na_loja'].Value);          
          DM_Json.QryRecebidas.Post;
        end;
        Result:=True;
        lHTTP.Free;
        lStream.Free;
      end;
    end;
  except
    on E : Exception do
    begin
      Result:=False;
      Principal.TraduzException('Erro: '+e.message,nil);
    end;
  end;
Responder

Gostei + 0

24/06/2015

Danilo Pereira

Dorivan fiz o teste com o LkJason também não deu certo, o meu problema é na hora de fazer o parse para TlkJSONobject, parece que ele não reconhece o json e ai o objeto vem null.

O Json que estou recebendo esta nesse formato:
[{"fone":"","inscMunicipal":"","bairro":"","nascimento":"1899-12-30T00:00:00.000Z","uf":"MG","inscEstRg":"","apelidoFantasia":".","cep":"","cnpjCpf":".","id":0,"numero":"","status":"T","razaoSocial":"CONSUMIDOR#","cidade":"","endereco":"","codigo":"000000","fazenda":[]]


Eu acho que ele não reconhece esse formato, tem alguma forma de driblar este problema?
Responder

Gostei + 0

24/06/2015

Dorivan Sousa

aqui http://jsonlint.com/ voce pode validar o json, vai dizer se é valido.

[{"fone":"","inscMunicipal":"","bairro":"","nascimento":"1899-12-30T00:00:00.000Z","uf":"MG","inscEstRg":"","apelidoFantasia":".","cep":"","cnpjCpf":".","id":0,"numero":"","status":"T","razaoSocial":"CONSUMIDOR#","cidade":"","endereco":"","codigo":"000000","fazenda":[]]


apresentou um erro
Parse error on line 21:
...             ]    ]
---------------------^
Expecting '}', ','


nao é um json valido. ta falando um "}' antes do ultimo "]"
Responder

Gostei + 0

24/06/2015

Danilo Pereira

Realmente estava faltando mesmo, só q agora esta dando outro erro: Invalid Class typeCast quando tenta fazer o parse

O Json é este:
[
    {
        "codigo": "000000",
        "status": "ATIVO",
        "razaoSocial": "CONSUMIDOR#",
        "apelidoFantasia": ".",
        "cpfCnpj": ".",
        "inscEstRg": null,
        "inscMunicipal": "13",
        "fone": null,
        "endereco": {
            "nomeLogradouro": null,
            "numero": "",
            "bairro": null,
            "cidade": null,
            "uf": "MG",
            "cep": null
        },
        "nascimento": null,
        "cupons": [],
        "fazendas": []
    }
]
Responder

Gostei + 0

24/06/2015

Dorivan Sousa

posta o codigo que vc ta usando pra ler o objeto.
Responder

Gostei + 0

24/06/2015

Danilo Pereira

procedure TformPrincipal.Button2Click(Sender: TObject);
var
  js: TlkJSONobject;
  ja2, ja: TlkJSONlist;
  jsonString:String;
begin

  dm.RESTCliente.BaseURL := 'http://localhost:8080/WebServiceIntegracao/wscoopa/cliente/all';
  dm.RESTRequisicao.Method := TRESTRequestMethod.rmGET;
  dm.RESTRequisicao.Resource := '';
  dm.RESTRequisicao.Execute;
  jsonString := dm.RESTResposta.JSONValue.ToString;

  js := TlkJSON.ParseText(jsonString) as TlkJSONobject;

end;


O erro ocorre nessa linha: js := TlkJSON.ParseText(jsonString) as TlkJSONobject;
Responder

Gostei + 0

24/06/2015

Danilo Pereira

Dorivan o método que eu tinha feito era este, ele só funciona se eu passar um json q tenha apenas um objeto, se eu passar uma lista ele da errado.

function THelper.JsonToObjeto(valorString: String;classe: TClass): TObject;
var unMarshal : TJSONUnMarshal;
    valorJson: TJSONValue;
begin
    unMarshal := TJSONUnMarshal.Create;
    valorJson := TJSONObject.ParseJSONValue(valorString);
    result := (unMarshal.CreateObject(classe,TJSONObject(valorJson)));
end;
Responder

Gostei + 0

24/06/2015

Dorivan Sousa

esse é detalhe
voce tem q levar em consideracao o que vc ta recebendo, voce recebe uma list entao temq tratar uma lista.. o codigo abaixo faz o tratamento correto do seu formato de json

var
  Json: WideString;
  e, i: integer;

  jl: TlkJSONlist;
  ja: TlkJSONobject;
begin
  try
    Json:=Edit1.Text;
    if Length(Json) > 0 then
    begin
      jl := TlkJSON.ParseText(Json) as TlkJSONlist;

      if assigned(jl) then
      begin
        ja := jl.child[0] as TlkJSONobject;

        pessoa.EmptyDataSet;
        pessoa.Append;
        pessoacodigo.AsString:=VarToStr(ja.Field['codigo'].Value);
        pessoastatus.AsString:=VarToStr(ja.Field['status'].Value);
        pessoarazaoSocial.AsString:=VarToStr(ja.Field['razaoSocial'].Value);
        pessoaapelidoFantasia.AsString:=VarToStr(ja.Field['apelidoFantasia'].Value);
        pessoacnpjCpf.AsString:=VarToStr(ja.Field['cpfCnpj'].Value);
        pessoainscEstRg.AsString:=VarToStr(ja.Field['inscEstRg'].Value);
        pessoainscMunicipal.AsString:=VarToStr(ja.Field['inscMunicipal'].Value);
        pessoafone.AsString:=VarToStr(ja.Field['fone'].Value);

        Pessoaendereco.AsString:=VarToStr(ja.Field['endereco'].Field['nomeLogradouro'].Value);
        Pessoanumero.AsString:=VarToStr(ja.Field['endereco'].Field['numero'].Value);
        Pessoabairro.AsString:=VarToStr(ja.Field['endereco'].Field['bairro'].Value);
        Pessoacidade.AsString:=VarToStr(ja.Field['endereco'].Field['cidade'].Value);
        Pessoauf.AsString:=VarToStr(ja.Field['endereco'].Field['uf'].Value);
        Pessoacep.AsString:=VarToStr(ja.Field['endereco'].Field['cep'].Value);

        pessoa.Post;
      end else
        ShowMessage('não carregou a lista');
    end;
  except
    on E : Exception do
    begin
      ShowMessage('Erro: '+e.message);
    end;
  end;
Responder

Gostei + 0

24/06/2015

Dorivan Sousa

outra solucao pra usar o seu codigo é so vc remover o [ do inicio e ] do fim com copy

tem q entender a extrutura do json que vc ta trabalhando

function THelper.JsonToObjeto(valorString: String;classe: TClass): TObject;
var unMarshal : TJSONUnMarshal;
    valorJson: TJSONValue;
begin
    valorString:=trim(valorString); //remove os esaços em branco no inicio e no fim se houver
    valorString:=Copy(valorString,2,length(valorString)); //remove o primeiro colchete
    valorString:=Copy(valorString,1,length(valorString)-1); //remove o ultimo colchete


    unMarshal := TJSONUnMarshal.Create;
    valorJson := TJSONObject.ParseJSONValue(valorString);
    result := (unMarshal.CreateObject(classe,TJSONObject(valorJson)));
end;
Responder

Gostei + 0

24/06/2015

Danilo Pereira

Dorivan no meu caso sempre vou receber uma lista, como eu faria para percorrer essa lista? Estou passando os dados em um objeto e depois adiciono ele em uma lista, tentei colocar um FOR só q ele ta pegando sempre o primeiro valor que ta vindo do Json.
Responder

Gostei + 0

25/06/2015

Danilo Pereira

Dorivan deu certo, salva certinho na lista:

procedure TformPrincipal.Button2Click(Sender: TObject);
var
  jl: TlkJSONlist;
  ja: TlkJSONobject;
  jsonString:String;
  lista: TList<TCliente>;
  i: integer;
  cliente: TCliente;
begin
  lista := TList<TCliente>.Create;
  ja := TlkJSONobject.Create;
  jl := TlkJSONlist.Create;

  dm.RESTCliente.BaseURL := 'http://localhost:8080/WebServiceIntegracao/wscoopa/cliente/all';
  dm.RESTRequisicao.Method := TRESTRequestMethod.rmGET;
  dm.RESTRequisicao.Resource := '';
  dm.RESTRequisicao.Execute;
  jsonString := dm.RESTResposta.JSONValue.ToString;


  jl := TlkJSON.ParseText(jsonString) as TlkJSONlist;

  if Assigned(jl) then
    begin
     for i := 0 to jl.Count-1 do
       begin
        ja := jl.Child[i] as TlkJSONobject;
        cliente := TCliente.Create;
        cliente.codigo := VarToStr(ja.Field['codigo'].Value);
        cliente.razaoSocial := VarToStr(ja.Field['razaoSocial'].Value);
        cliente.status := VarToStr(ja.Field['status'].Value);
        cliente.apelidoFantasia := VarToStr(ja.Field['apelidoFantasia'].Value);
        cliente.cnpjCpf := VarToStr(ja.Field['cpfCnpj'].Value);
        cliente.inscEstRg :=VarToStr(ja.Field['inscEstRg'].Value);
        cliente.inscMunicipal := VarToStr(ja.Field['inscMunicipal'].Value);
        lista.Add(cliente);
       end;
    end;
end;



Outra coisa q eu queria saber, se aquele método q eu tinha feito antes, tem alguma maneira de fazer ele com lista, porque ele fica sendo genérico. Muito obrigado pela ajuda.
Responder

Gostei + 0

25/06/2015

Dorivan Sousa

acredito que tenha como mas nao to familiarizado com o comando, venho estudando justamente isso pra migrar minha aplicacao pra 3 camadas onde toda a comunicacao com o servidor será por Json e o cliente com MVC, um framework ORM.
acho que a solucao é com generics. no seu codigo voce ta recebendo uma lista e ta tentando jogar essa liga em um só objeto, o que fazer é usar uma lista desse objeto

http://www.andreanolanusse.com/pt/utilizando-generics-para-transformacao-generica-de-objetos-em-datasnap-2010/
Responder

Gostei + 0

29/06/2015

Pro.sys.poa

Boa noite pessoal,

Estive acompanhando a troca de informações entre vcs e pergunto:
- Vcs utilizam ou sabem se existe uma forma de utilizar os componentes TRestCliente/TRestRequest/TRestResponse no Delphi XE3?

Pergunto, pois preciso recuperar um json de uma API de conexão que utiliza o protocolo HTTP seguindo o modelo RestFull. E esta conexão possui parâmetros o "header" HTTP.

Consegui realizar com estes componentes via XE8, mas a aplicação que precisa recuperar estes dados é em XE3.

Obrigado.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar